基础
导入包
由于字符集和字体相关问题,必须进行两项设置,使图上中文无乱码
代码中涉及的字体要支持中文,这里SimSun是宋体,若换成Times New Roman,则依然无法显示中文
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False
新建一块画板,初始化一张图
fig相当于画板,可以设置标题等属性
axe代表一张子图,可以进行各类设置并绘图
figsize控制画板绘图区的大小和形状,后面有一节详述
fig, axe = plt.subplots(1,1,figsize=(6.4, 3.6))
新建一块画板,初始化多张子图
axes是一维数组,axes[i]表示从左向右第i个图。figsize是整个图的大小而不是单个子图的大小
fig, axes = plt.subplots(1,2,figsize=(12.8, 3.6))
sharey参数表示两个子图共用y轴
二维阵列图同理,sharey和sharex都可以为True,使用axes[i,j]索引子图
fig, axes = plt.subplots(2,2,sharey=True,figsize=(12.8, 3.6))
多子图不同宽度或高度
f, (a0, a1) = plt.subplots(2,2, gridspec_kw = {'width_ratios':[3, 1]})
画图
plot折线图
最基本的画图,以x和y两个数组画折线图,数据点不会突出显示
若只指定y_array,x_array默认为[0,len(y_array)-1]
plot(x_array, y_array, "r--",label="图例1")
plot(y_array, color="#505050", linestyle="--",marker="o",label="图例2")
特殊写法,用于画直线,如标注水平或垂直基准线,参考https://matplotlib.org/stable/gallery/lines_bars_and_markers/vline_hline_demo.html
vax.vlines([1, 2], 0, 1, transform=vax.get_xaxis_transform())
hist直方图
分界方式
默认的分界方式的界可能是任何数字,不一定是5的倍数、10的倍数等较整的数值。而在需求上,直方图分界点的取值常用一些整倍数。如一组数据分布在73-122之间,区间长度为5,那么分界点应当为70,75,80,……,120,125。下面的函数计算了第一个和最后一个分界点的位置,以及区间的个数,用于这些需要整数的场合
def cal_min_max_bins(data, interval):
maxd, mind = max(data), min(data)
mind = floor(mind / interval)
maxd = ceil(maxd / interval)
bins = maxd - mind
maxd *= interval
mind *= interval
return mind, maxd, bins
当纵坐标为频数时:
distribute, edges,_=axe.hist(data,bins=bins,range=(mind, maxd),label="图例标签")
参数说明:
- data:要分类的数据
- bins:区间个数
- range:区间的最小值和最大值
- label:图例标签
这三个参数都可以由上面的函数计算得到
返回值说明:
wieght=1/len(data)
distribute, edges,_ = axe.hist(data,bins=bins,range=(mind, maxd),weights=tuple(weight for i in data))
weights用于把频数变为频率,长度和数据个数相同,每个值都是1/len(data)
其他要素
对同一个axe画多次hist可以同图显示,alpha可以透明,用于多图叠加对比
distribute, edges,_ = axe.hist(data,bins=bins,range=(mind, maxd),alpha=0.5)
默认样式的各区间之间没有边框分割,如果需要,可以使用:
distribute, edges,_ = axe.hist(data,bins=bins,range=(mind, maxd),edgecolor="black")
如果不需要画图,只是想统计数据的分布情况:
import numpy as np
wieght=1/len(data)
#distribute:每个柱子的高度
#edges:每个柱子的分界点,长度为柱子的数量+1
distribute, edges = np.histogram(data,bins=bins,range=(mind, maxd),weights=tuple(weight for i in data))
在图上标注文本
for i in range(len(y_array)):
axe.text(x_array[i],y_array[i], f"点{i}",ha='center',va='bottom',transform=axe.transAxes)
参数说明如下:
前3个: 标记点的x坐标,标记点的y坐标,标注文字
ha: 标记点作为文本框的左侧,中间还是右侧
va: 标记点作为文本框的顶部,中间还是底部
transform=axe.transAxes: 可选参数。不采用坐标决定位置,而是采用相对x轴和y轴的百分比作为单位
坐标轴设置
子图标题和坐标轴设置
axe.set(xlim=[0,20])
只要是set函数能识别的参数,都有对应的单函数形式,如set_title
、set_xlim
等,它们的好处使可以有其他参数,后文详述
常用设置:
- xlabel,ylabel:坐标轴名称,如时间,电流等
- xticks,yticks:坐标轴数值,如[20,21,22,23,24,25]
- xticklabels,yticklabels:坐标轴数值可以改成文本,如[“Jan”,”Feb”,”Mar”]
- xlim,ylim:坐标轴最小和最大值,类型为元组,如(18,27)
获取项目要在项目名称之前加get_
,形如get_xticks
。
精确设置
手动指定刻度对应的文本
axes.set_xticks([20,21,22,23], labels=["昨天","今天","明天","后天"], minor=False)
设置刻度间距
把x轴的主刻度设置为m的倍数
ax.xaxis.set_major_locator(plt.MultipleLocator(m))
ax.xaxis.set_minor_locator(plt.MultipleLocator(m))
MultipleLocator显示的都是m的倍数的点,比如m=3,对于数列3,4,5,6,7,8,9,10
,会显示3,6,9
,默认的LinearLocator显示的只能保证显示的刻度之间等距,有可能会显示4,7,10,13
设置刻度格式
标准写法表示普通浮点数
ax.xaxis.set_major_formatter( plt.FormatStrFormatter('%1.1f'))
ax.xaxis.set_minor_formatter( plt.FormatStrFormatter('%1.1f'))
简约写法表示百分比方式
ax.xaxis.set_major_formatter("{:.1%}".format)
特殊情况:双Y轴图
双y轴图不要使用legend
ax_I = plt.subplots(1, 1)
ax_U = ax_I.twinx()
标注与格式
画板标题
#整张图片的总标题
fig.suptitle("总标题")
#plt.show的Windows窗口的标题
fig.canvas.set_window_title("Windows标题")
#每个子图自己的标题
axe.set_title("子图标题")
子图紧密排列
fig.subplots_adjust(wspace=0, hspace=0)
图像周围白边
数值是图像(若有子图则是所有子图的整体)在画布上的位置,以画布的长和宽分别为单位1
fig.subplots_adjust(left=0.1, top=0.95, bottom=0.05, right=0.75)
字体和字号
修改本项目的全局设置,覆盖了标题、坐标轴名称和坐标轴标签等所有元素的字号。字体同理
plt.rcParams['font.size'] = 20
plt.rcParams['font.sans-serif'] = ['SimSun']
常用项目字体设置
axe.set_title("aaa", fontdict={'family' : 'Times New Roman', 'size' : 16})
axe.set_ylabel('yyy', fontdict={'family' : 'Times New Roman', 'size' : 16})
axe.set_xticklabels(xlabels,fontdict={'family' : 'Times New Roman', 'size' : 16})
axe.text(...,fontdict={'family' : 'Times New Roman', 'size' : 16})
axe.legend(prop={'family' : 'Times New Roman', 'size' : 16})
xticklabels
如果只需要更改字体,可以采用如下写法:
axe.set_xticklabels(axe.get_xticklabels(),fontdict={'family' : 'Times New Roman', 'size' : 16})
上下标、斜体和数学公式
上下标也是一种简单的公式,在任何需要输入公式的字符串输入latex公式即可,会自动设置为公式标准样式,如:
速度($v{\cdot}s^{-1}$)
效果为
%0A#card=math&code=%E9%80%9F%E5%BA%A6%28v%7B%5Ccdot%7Ds%5E%7B-1%7D%29%0A&id=zlqHW)
公式字体推荐设置为stix,样式接近于Times New Roman
plt.rcParams['mathtext.fontset'] = 'stix'
显示与保存
显示绘制的图片
释放已生成的画板资源,当已经绘制了很多画板,又不再需要使用时,减轻电脑负担。被关闭的图在plt.show()时不会显示
#关闭一张图
plt.close(fig)
#关闭所有
plt.close()
显示所有未关闭的图
plt.show()
保存绘制的图片
正常保存
fig.savefig("aa.png")
若保存的图片不完整,一般是因为调整了字体大小。解决办法:
fig.tight_layout()
fig.savefig("aa.png")