科技论文绘图模板
1. 基本头文件
import numpy as np
import matplotlib.pyplot as plt
import scipy.io as scio
import matplotlib
import scipy
import scipy.stats
只绘图的话上面的几个包基本够用,我一般的搞法是用MATLAB把数据处理成最终的结果,然后在python环境中直接把图plot出来。根据以前的经验,这样弄的好处是python环境下,在不同分辨率的电脑系统中,图形的大小好像保持一致,但是用MATLAB处理之后保存的图片,在不同分辨率下的系统环境中编译出来的文件,放到latex环境下会出现字体大小不一致的问题。
2. 指定字体
from matplotlib import rcParams
#rcParams['font.family']='sans-serif'
rcParams['font.family']='sans-serif'
rcParams['font.sans-serif']=['Arial']
利用上面的文件,将图片上面出现的字体指定为Arial,当然你也可以指定其它的字体,记得全文统一就行。这里指定字体的问题是,很多投稿系统要求字体嵌入,但是当我们不指定字体的时候,在不同系统环境(如中、英文系统)下,编译出来的图片文件生成的字体会不一样,这个时候,你再用Adoba去完成字体嵌入时(最简单的办法是保存成PDF/A的格式即可完成字体嵌入),在不同的电脑下就得采用不同的模板。
3. 绘图的基本代码
error_domain = np.squeeze(np.loadtxt('error_domain.txt'))
# error_test = np.loadtxt('error_test.txt')
def get_data(dataset):
data_size=len(dataset)
data_set=sorted(set(dataset))
bins=np.append(data_set, data_set[-1]+1)
# Use the histogram function to bin the data
counts, bin_edges = np.histogram(dataset, bins=bins, density=False)
counts=counts.astype(float)/data_size
# Find the cdf
cdf = np.cumsum(counts)
x = bin_edges[0:-1]
return x, cdf
font_size = 20
plt.figure()
#x, cdf = get_data(error_test)
#plt.plot(x, cdf, linewidth = 3, color = 'g', label = u'Test sample')
x, cdf = get_data([i + 2*np.squeeze(np.random.rand()) for i in error_domain])
plt.plot(x, cdf, linewidth = 3, color = 'k', linestyle='--', label = u'Solid wood')
x, cdf = get_data([i + 12*np.squeeze(np.random.rand()) for i in error_domain])
plt.plot(x, cdf, linewidth = 3, color = 'b', linestyle='-.', label = u'Engineered wood')
x, cdf = get_data([i + 16*np.squeeze(np.random.rand()) for i in error_domain])
plt.plot(x, cdf, linewidth = 3, color = 'r', linestyle=':', label = u'Concrete')
plt.xlabel('Errors (cm)', fontsize = font_size)
plt.ylabel('CDF', fontsize = font_size)
plt.tick_params(labelsize=font_size)
plt.legend(loc='lower right',prop={'size':15})
plt.grid(True)
plt.subplots_adjust(left=0.16, right = 0.98, top = 0.98, bottom = 0.175)
plt.savefig('./floor.pdf', transparent=True)
plt.show()
这个模板保证了每次更改的时候,图片的大小,占用的空间,里面的字体什么的都能完全一致,非常的方便
其它一些小工具:
如将x,y 轴设定为采用科学记数法:
ax.yaxis.get_major_formatter().set_powerlimits((0,1)) # 将坐标轴的base number设置为一位。
ax.xaxis.get_major_formatter().set_powerlimits((0,1))
下面的代码为几个不同的子figure共享X轴:
fontsize=18
fontsize2 = 15
plt.figure()
plt.subplot(3,1,1)
plt.plot(length, noisy, c = 'b')
plt.title('Noisy signal',fontsize=fontsize)
plt.tick_params(labelsize=fontsize2)
ax = plt.gca()
ax.get_xaxis().set_visible(False)
plt.subplot(3,1,2)
plt.plot(length, denoised, c = 'g')
plt.title('Denoised signal',fontsize=fontsize)
plt.ylabel('Signal value',fontsize=fontsize)
plt.tick_params(labelsize=fontsize2)
ax = plt.gca()
ax.get_xaxis().set_visible(False)
plt.subplot(3,1,3)
plt.plot(length, original, c = 'r')
plt.title('Orginal signal',fontsize=fontsize)
plt.xlabel('Time (s)',fontsize=fontsize)
plt.tick_params(labelsize=fontsize2)
plt.subplots_adjust(hspace=0)
采用柱状图来比较不同的系统性能的完整代码模板:
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 16 08:32:42 2021
@author: Administrator
"""
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as mpatches
from matplotlib import rcParams
#rcParams['font.family']='sans-serif'
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Arial']
# plt.rcParams['xtick.direction'] = 'in'
# plt.rcParams['ytick.direction'] = 'in'
font_size = 25
# plt.figure(figsize=(20, 8), dpi=80)
plt.figure()
year = ['1','2','3', '4', '5']
data1 = [72.2, 73.6, 78.2, 88.4, 91.7] # Distance
data2 = [58.2, 60.2, 67, 79, 82] # Speed
data3 = [25, 34.2, 54.4, 63.6, 68.5] # Env
data4 = [7, 13.3, 34.5, 59.7, 64.3] # Footwear
# 先得到year长度, 再得到下标组成列表
x = range(len(year))
plt.bar(x, data1, width=0.2, color='#FF6347')
# 向右移动0.2, 柱状条宽度为0.2
plt.bar([i + 0.2 for i in x], data2, width=0.2, color='#008B8B')
plt.bar([i + 0.4 for i in x], data3, width=0.2, color='#FF00FF')
plt.bar([i + 0.6 for i in x], data4, width=0.2, color='#6495ED')
# 底部汉字移动到两个柱状条中间(本来汉字是在左边蓝色柱状条下面, 向右移动0.1)
plt.xticks([i + 0.3 for i in x], year)
plt.ylabel('Accuracy (%)', size=font_size)
plt.xlabel('Domain number', size=font_size)
color = ['#FF6347', '#008B8B', '#FF00FF', '#6495ED']
labels = ['Case1', 'Case2', 'Case3', 'Case4']
plt.tick_params(labelsize=font_size)
patches = [mpatches.Patch(color=color[i], label="{:s}".format(labels[i]) ) for i in range(len(color))]
ax=plt.gca()
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width , box.height])
#下面一行中bbox_to_anchor指定了legend的位置
ax.legend(handles=patches, bbox_to_anchor=(0.99,1.12), ncol=4, fontsize = 12) #生成legend
# 为每个条形图添加数值标签
# for x1,y1 in enumerate(data1):
# plt.text(x1, y1+0.1, y1,ha='center',fontsize=font_size)
# for x2,y2 in enumerate(data2):
# plt.text(x2+0.2,y2+0.1,y2,ha='center',fontsize=font_size)
plt.subplots_adjust(left=0.14, right=0.985, top=0.905, bottom=0.18)
plt.savefig('./impact_of_domain.pdf', transparent=True)
plt.show()
相应的输出图形状为:
基本线形图模板:
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as mpatches
from matplotlib import rcParams
import scipy.io
#rcParams['font.family']='sans-serif'
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Arial']
font_size = 25
# plt.figure(figsize=(20, 8), dpi=80)
plt.figure()
x = scipy.io.loadmat('real_peak.mat')
x = np.squeeze(x['signal_voltage'])
y = scipy.io.loadmat('peak_matrix.mat')
y = np.squeeze(y['peak'])
f = scipy.io.loadmat('frequency_value.mat')
f = np.squeeze(f['frequency_value'])
color = ['#FF6347', '#008B8B', '#FF00FF', '#6495ED', '#FF0000', '#6A5ACD']
linestyle = ['-', '--', '--', '--', '--', '--']
marker = ['', '^', '*', '+', 'o', 'v']
label = [ f'{i}MHz' for i in f]
for i in range(len(x)):
plt.plot(x, y[i, :]/1000, linewidth = 3, color = color[i], marker = marker[i], linestyle = linestyle[i], label = label[i])
plt.ylabel('Input voltage (V)', size=font_size)
plt.xlabel('Output voltage (V)', size=font_size)
plt.legend(loc='upper left',prop={'size':15})
plt.tick_params(labelsize=font_size)
plt.subplots_adjust(left=0.18, right=0.985, top=0.965, bottom=0.22)
plt.savefig('./peak_performance.pdf', transparent=True)
plt.show()
输出结果:
画线型图的时候注意,最好是用不同的线型linestyle把不同的输入输出区分开来,当线型不够用的时候就用marker来区分,第一条线最好是用实线,剩下的其它的线用虚线。
稍微复杂点的标注应用:
# -*- coding: utf-8 -*-
"""
Created on Wed Jan 12 16:50:22 2022
@author: Administrator
"""
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as mpatches
from matplotlib import rcParams
import scipy.io
#rcParams['font.family']='sans-serif'
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Arial']
font_size = 25
# plt.figure(figsize=(20, 8), dpi=80)
plt.figure()
x = scipy.io.loadmat('time.mat')
x = np.squeeze(x['Time'])
peak = scipy.io.loadmat('peak_pulse.mat')
peak = np.squeeze(peak['temp_peak_pulse']) / 1000
osc = scipy.io.loadmat('OS_pulse.mat')
osc = np.squeeze(osc['temp_OS_pulse']) / 1000
plt.plot(x, peak, linewidth = 3, color = 'r', label = u'Peak output')
plt.plot(x, osc, linewidth = 3, color = 'b', label = u'Square input')
# plt.axvline(1, linewidth = 3, linestyle = '--', color = 'g')
plt.axhline(101.2 / 1000, linewidth = 3, linestyle = '--', color = 'gray')
plt.axhline(910.8 / 1000, linewidth = 3, linestyle = '--', color = 'gray')
x_start = 100
plt.plot([x_start, x_start], [-0.200, 0.101], c = 'g', linewidth = 3, linestyle = '--')
x_end = 450
plt.plot([x_end, x_end], [-0.200, 0.910], c = 'g', linewidth = 3, linestyle = '--')
plt.annotate("%10 of Max.", xy=(1000, 101/1000), xytext=(-15, +20), textcoords='offset points', fontsize=15,arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=.2'))
plt.annotate("%90 of Max.", xy=(1000, 910/1000), xytext=(-15, -30), textcoords='offset points', fontsize=15,arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=.2'))
plt.text(220, -0.050, '$\Delta t_R$', ha='left', fontsize = 18, color = 'r', rotation=0, wrap=True)
# plt.annotate("$\Delta t_R$", xy=(250, 120), xytext=(-15, -20), textcoords='offset points', fontsize=18,arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=.2'))
ax = plt.gca()
# ax.yaxis.get_major_formatter().set_powerlimits((0,1))
plt.xlabel('Time (ns)', size=font_size)
plt.ylabel('Voltage (V)', size=font_size)
plt.ylim(-0.200, 1.350)
plt.legend(loc='upper right',prop={'size':15})
plt.tick_params(labelsize=font_size)
plt.subplots_adjust(left=0.17, right=0.985, top=0.98, bottom=0.19)
plt.savefig('./response_time_metric.pdf', transparent=True)
plt.show()
输出结果为: