一、基本使用流程
import matplotlib.pyplot as plt # 导入模块
# 画布设置
plt.figure(figsize=(12,9)) # 设置图像尺寸大小,参数值乘以100表示分辨率
plt.subplot(m,n,j) # 多个图排列
plt.figure().tight_layout() # 多个图排列时自动设置间距,消除重叠
# 画图
plt.plot(x, y)
# 图形设置
plt.xlabel( 'height') # 设置X轴标题
plt.ylabel( 'weight ') # 设置Y轴标题
plt.title('scatter demo') # 添加图的标题
# 保存与显示
plt.savefig(savepath) # 保存图像,图像如果不完整,需要添加参数 bbox_inches = 'tight'
plt.show() # 显示图像,执行该语句之后会释放 figure 资源,如果要保存图片必须将 save 放在 show 之前,否则只能保存空白
二、常见设置
1.设置画布尺寸
plt.figure(
figsize=(30, 5), # 画布大小,指定画布的宽和高,单位为英寸
dpi=80 # 指定绘图对象的分辨率,即每英寸对少个像素,默认为80
)
2.设置坐标轴刻度、标签、标题
plt.xticks(
x, # 刻度,就是坐标轴上的一个个短划线
x_ticks_label, # 刻度标签,短划线旁边的字符串
rotation # 刻度标签旋转角度
)
plt.xlabel('x_axle')
3.设置坐标轴显示范围
plt.xlim([4, 8]) # 两边都设置
plt.xlim(xmin=4) # 只设置左边
plt.xlim(xmax=4) # 只设置右边
4.设置坐标轴显示方式
ax = plt.gca()
ax.spines['right'].set_color('none') # 隐藏右边线
#ax.spines['right'].set_visible(False) # 效果相同
ax.spines['top'].set_color('none') # 隐藏上边线
ax.spines['left'].set_color('b') # 左边线颜色为蓝色
ax.spines['bottom'].set_color('y') # 下边线颜色为黄色
ax.spines['left'].set_position(('data', 6)) # 移动左边线,'data' 表示移动到交叉轴的指定坐标
5.设置双坐标轴
双坐标轴一般用于复合图表,同时表示两种图表的指标量纲不一,经典的使用场景如帕累托图。使用中,需要对原有的ax
使用.twinx()
方法生成ax2
,再利用ax2
进行绘图。
fig, ax = plt.subplots()
ax.plot(['x1', 'x2', 'x3'], [1,2,3], color='r')
# 双坐标法
ax2 = ax.twinx()
ax2.bar(['x1', 'x2', 'x3'], [20,40,60], color='b', alpha=0.5)
6.设置标题
# 第一种方式
plt.title(
label='title',
fontdict={'size':20},
loc='right',
pad=None
)
# 第二种方式
fig,ax = plt.subplots()
ax.set_titlelabel='ax_title',
fontdict={'size':20},
loc='right',
pad=None
)
7.设置网格
plt.grid(
b=None, # 是否显示网格线
axis='both', # 方向轴
linestyle='-.', # 网格线样式
linewidth=2, # 线宽
alpha=.4, # 透明度
color='red' # 颜色
)
8.设置图例
图例在一图多线中使用,第一种设置方式:划线时在 plt.plot 中设置 label 参数,然后使用 legend;第二种设置方式:直接使用 legend 按照顺序设置。
plt.plot(x, y, c='r', label='line1')
plt.plot(x, y**2, c='b', label='line2')
plt.legend(
prop, # 图例字体,可设置为下面第 9 条中的 my_font
loc='upper right' # 图例位置
)
# 或者在 plot 中不使用 label 参数,直接使用如下语句
# 顺序遵从 plot 的画线顺序
# plt.legend(['line1', 'line2'])
9.设置显示中文(局部)
一般用来设置中文的属性都是 fontproperties
,除了图例用的是 prop
,这个在上面说到过!
from matplotlib import font_manager
# 设置字体,这个字体文件必须支持中文
my_font = font_manager.FontProperties(fname='/path/to/font_file.ttc', size=18)
# 坐标轴显示中文
plt.xlabel(
x_title, # 坐标轴标题内容
fontproperties=my_font # 字体设置
)
# 图形标题显示中文
plt.title(
title,
fontproperties=my_font
)
10.设置中文显示(全局)
plt.rcParams['font.sans-serif'] = ['FangSong']
'''
常用字体:
- 黑体 SimHei
- 微软雅黑 Microsoft YaHei
- 微软正黑体 Microsoft JhengHei
- 新宋体 NSimSun
- 新细明体 PMingLiU
- 细明体 MingLiU
- 标楷体 DFKai-SB
- 仿宋 FangSong
- 楷体 KaiTi
- 仿宋_GB2312 FangSong_GB2312
- 楷体_GB2312 KaiTi_GB2312
'''
11.创建多个子图
fig = plt.figure(num=1, figsize=(10,10))
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
ax4 = fig.add_subplot(2,2,4)
12.任意位置添加文字
plt.text(
x, # 横坐标
y, # 纵坐标
text, # 内容
c, # 颜色
size, # 字体大小
ha='center', # 对齐方式
fontproperties=my_font # 字体
)
13.显示LaTeX公式
matplotlib 自带有几种数学字体:dejavusans, dejavuserif, cm, stix, stixsans, custom
,最常用的有 cm
系列和 stix
系列,前者是 Latex 默认的数学字体,而 stix
的正体和 Times New Roman
差别很小,一般用来和 Times New Roman
搭配。
import matplotlib.pyplot as plt
# ['dejavusans', 'dejavuserif', 'cm', 'stix', 'stixsans', 'custom']
plt.rcParams['mathtext.fontset'] = 'cm'
ax = plt.subplot(111)
ax.text(0.1, 0.8, r"$\int_a^b f(x)\mathrm{d}x$", fontsize=30, color="red")
ax.text(0.1, 0.3, r"$\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}!$", fontsize=30)
plt.show()
三、基本图形绘制
1.折线图
plt.plot(
x, # 横坐标
y, # 纵坐标
color='r', # 折线颜色
alpha=0.5, # 折线透明度
linestyle='--', # 折线的样式,-./
linewidth=3, # 折线宽度
marker='o' # 折点样式,*/+/x/s/v/h/H
)
2.散点图
plt.scatter(
x,
y,
c='r',
marker='s',
alpha=.5,
label='test'
)
3.条形图
条形图绘制时会返回所有绘制的矩形框,这些矩形框也是一个个的对象!
# 垂直条形图
rects = ax1.bar(x, y, color='r', width=0.3, alpha=.5)
for rect in rects:
print(rect.get_x(), rect.get_y())
print(rect.get_width(), rect.get_height())
# 水平条形图
ax2.barh(x, y, color='r', height=0.3, alpha=.5) # 这里条形宽度其实是高度 height
# 并列条形图
ax3.bar(x, y, color='r', width=0.3, alpha=.5)
ax3.bar(x+0.3, y-1, color='b', width=0.3, alpha=.5) # 这里 x 偏移与宽度一致
# 罗列条形图
ax4.bar(x, y, width=0.3, alpha=.5) # 先画下面的
ax4.bar(x, y-1, bottom=y, color='r', width=0.3, alpha=.5) # 再画上面的,用 bottom 把它顶起来
4.直方图
直方图带有统计功能,它会统计落在每一个区间内的样本数量,然后绘制矩形,所以输入需要是一个样本集合
plt.hist(
x, # 数据样本集合
bins # 区间的数量,它会根据这个参数、以及数据的最大最小值自动计算每一个区间的上下界
)
# 区间数量的计算方式:最大样本值减去最小样本值,除以区间宽度,最后取整
bins = int((max(x)-min(x))/region_width)
5.饼状图
size = [59, 20, 21] # 每一部分占比
clolor = ['r', 'g', 'b'] # 每一部分颜色
explode = [0, 0.1, 0] # 每一部分凸出比例
label_list = ['梅西', 'C罗', '内马尔'] # 每一部分标签
# 绘制饼状图
patches, l_text, p_text = plt.pie(
size,
explode=explode, # 凸出
colors=clolor, # 颜色
labels=label_list, # 标签
labeldistance=1.4, # 各部分标签距离圆心距离,按照半径的倍数计算
pctdistance=0.7, # 圆内各扇形文本距离圆心距离,按照半径的倍数计算
autopct='%.1f%%', # 圆内各扇形文本显示格式,就是半分比
shadow=True, # 圆内各扇形边界阴影
startangle=90, # 第一个扇形的起始角度,从第一象限逆时针开始计算
)
# 重新绘制扇形颜色
for t in patches:
t.set_color('pink')
break
# 绘制标签
for t in l_text:
t.set_fontproperties(my_font)
# 绘制扇形内文本(百分比标签)
for t in p_text:
t.set_size(15)
# 绘制图例
plt.legend(prop=my_font)
四、实例展示
1、实例一
基本画图操作,得到一般科研用图。
def draw(train_data, valid_data=None, ylabel='Loss'):
'''
train_data:
valid_data:
ylabel:
'''
x_ticks = np.arange(0, len(train_data), 1)
y_min = math.floor(min(train_data) * 0.8)
y_max = math.ceil(max(train_data) * 1.1)
# 设置横坐标刻度
plt.xticks(x_ticks, x_ticks)
# 设置纵坐标范围
plt.ylim([y_min, y_max])
# 设置横坐标轴标题
plt.xlabel('Epoch')
# 设置纵坐标轴标题
plt.ylabel(ylabel)
ax = plt.gca()
# 隐藏右边线
ax.spines['right'].set_color('none')
# 隐藏上边线
ax.spines['top'].set_color('none')
# 设置网格
ax.grid(b=None, axis='y', linestyle='-.', linewidth=1, alpha=.2, color='g')
# 画图
ax.plot(range(len(train_data)), train_data, c='blue')
ax_legend = ['train_'+ylabel.lower()]
if valid_data!=None:
ax.plot(range(len(valid_data)), valid_data, c='red')
ax_legend += ['valid_'+ylabel.lower()]
# 设置图例
ax.legend(ax_legend)
得到的结果就如下图:
2、实例二
鼠标在已有图像上选择区域,将所选区域放大显示细节。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import SpanSelector
# Fixing random state for reproducibility
np.random.seed(19680801)
fig, (ax1, ax2) = plt.subplots(2, figsize=(8, 6))
ax1.set(facecolor='#FFFFCC')
x = np.arange(0.0, 5.0, 0.01)
y = np.sin(2 * np.pi * x) + 0.5 * np.random.randn(len(x))
ax1.plot(x, y, '-')
ax1.set_ylim(-2, 2)
ax1.set_title('Press left mouse button and drag to test')
ax2.set(facecolor='#FFFFCC')
line2, = ax2.plot(x, y, '-')
def onselect(xmin, xmax):
indmin, indmax = np.searchsorted(x, (xmin, xmax))
indmax = min(len(x) - 1, indmax)
thisx = x[indmin:indmax]
thisy = y[indmin:indmax]
line2.set_data(thisx, thisy)
ax2.set_xlim(thisx[0], thisx[-1])
ax2.set_ylim(thisy.min(), thisy.max())
fig.canvas.draw()
span = SpanSelector(ax1, onselect, 'horizontal',
useblit=True,
rectprops=dict(alpha=0.5, facecolor='red')
)
plt.show()
3、实例三
添加背景图。
import matplotlib.image as image
import matplotlib.pyplot as plt
im = image.imread('messi.png')
messi = [0, 3, 12, 31, 22, 41, 60, 59, 91, 45, 58, 52, 59, 54, 51, 50, 16]
year = list(range(2004, 2021))
fig, ax = plt.subplots()
ax.grid()
ax.plot(year, messi)
ax.set_title("Messi goals every year")
fig.figimage(im, cmap='ocean', alpha=.3, resize=True)
plt.show()