原文出处:https://www.jianshu.com/p/8006d74ac9e7
正常在matplotlib中画图这个过程其实是很简单的,往往就是调用一句plt.plot()或者plt.bar()然后将整理好的数据按照要求放进去就可以了,真正比较复杂的是对图表的各种设置,使图表明确、美观。这篇文章重点讲讲matplotlib中的各种设置操作。
1.显示中文字体
这个问题困扰笔者很久,因为matplotlib自己是不带中文字体的,如果有中文可能会显示方框,需要通过手动设置的方式才能正常显示,而对于mac和windows电脑设置方法又不同。下面我列举集中常见的设置方法:
1.1 通过rcParams()设置全局参数
首先简单说一下rcParams这个参数,这个参数用于控制图像的基础属性,如图像大小、像素、线条宽度、颜色、样式、坐标轴、坐标和网络属性、文本、字体等,可以说是首先对图像进行一个自定义操作。rcParams的各个参数存储在字典里。 用这个方法设置字体时,需要分windows和mac来考虑,基本设置语句为:
代码语言:javascript复制import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['font.serif'] = ['KaiTi']
#plt.rcParams['axes.unicode_minus'] = False # 这句和字体没有关系,但很可能有人也会遇到保存图像是负号'-'显示为方块的问题,或者转换负号为字符串的问题,使用这个语句可以避免。
windows自带的字体如下:
win自带字体
mac自带字体目前并没有人完全列出,但是'Arial Unicode MS'这种字体有人试验可以在mac上成功应用,笔者也亲试可用,大家如果对字体样式没有特别的美观要求,可以用这种方式设置。
代码语言:javascript复制plt.rcParams['font.family'] = ['Arial Unicode MS']
更多关于rcParams()的应用笔者建议大家可以根据实际遇到的问题进行探索,没必要特别去学习。
1.2 通过font_manager设置自定义字体
这种方法需要自己下载字体,这样相对就比较麻烦一些了,设置方法如下:
代码语言:javascript复制import matplotlib.font_manager as fm
myfont = fm.FontProperties(fname=r'D:Fontssimkai.ttf')
后来在设置字体的时候,比如label,title等指定字体为自定义的myfont,即给参数赋值fontproperties=myfont。
2.设置画布大小
设置画布大小通常是为了显示图标更加美观用,指定方式比较多。
2.1 建立画布的时候指定
首先,再来科普一下matplotlib的元素基础知识,figure代表整个图表对象,ax代表坐标轴和画的图,这两个要有区分。建立画布有两种模式,一是直接建好figure和ax,另外一种是先建立fig再建立ax,两种模式的画布设置方法不一样。 这里要说明一个什么问题呢,既然坐标轴和图像部分都是ax对象,那么通过ax肯定可以设置的,而plt控制着整个figure,因此通过plt也可以设置。二者有的时候有一点语法区别,一般plt是直接跟要设置的对象,比如设置x轴的标题名,你可以用plt.xlabel(),ax一般是加个set之后再跟要设置的对象,同样的问题,可以用ax.set_xlabel()。
代码语言:javascript复制#一次建立fig和ax设置画布大小方法
fig,ax = plt.subplots(2,2,figsize=(15,10))
#先建立fig再建立ax设置画布大小方法
fig = plt.figure(figsize=(15,10))
ax=fig.add_subplot(111)
ax.scatter()
2.2 已经建立画布后指定
由于种种原因,建立画布的时候你没有制定图片的大小,需要后续设置,这个时候可以用fig.set_figheight(15)和f.set_figwidth(15)指定图片的大小。
3.设置坐标轴
坐标轴是ax对象里可以设置的东西,当然也可以通过plt直接设置。
3.1 设置坐标轴名称
这个就是我们常说的x轴和y轴名称,设置方法非常简单,用plt.xlabel和plt.ylabel指定,这个值得注意的是,如果是自定义的中文字体,可以指定字体样式。通常的使用格式是:
代码语言:javascript复制plt.xlabel(xlabel, fontdict=None, labelpad=None, **kwargs)
plt.ylabel(ylabel, fontdict=None, labelpad=None, **kwargs)
值得注意的是这个xlabel和ylabel支持类似于markdown语法的公式。
3.2 设置坐标轴显示范围
这个是指坐标轴的数据范围,用plt.xlim和plt.ylim,可以直接指定x轴和y轴的长度。举个简单的例子:
代码语言:javascript复制plt.xlim((-5, 5))
plt.ylim((-2, 2))
3.3 设置坐标轴图刻度
刻度有两种形式,一种是原来的初始数据形式,另外一种是自己想用的字符串形式,可以用xticks和yticks进行设置。
代码语言:javascript复制#初始数据格式
plt.xticks([1,2,3,4,5,6])
#文字格式
plt.xticks([1,2,3],[r'A',r'B',r'C'])
当然坐标轴是ax级别的元素,也可以通过ax进行设置,方法是ax.set_xticks、ax.set_xticks、ax.set_xticklabels和ax.set_yticklabels进行设置,区别在于一个生成数字刻度,一个生成文字刻度。和plt设置的不同在于,这个会根据图表省略一些刻度值,已满足图表的美观要求。建议用第一种。
代码语言:javascript复制#数字格式
labels = ax.set_xticks([1,2,3,4,5])
#文字格式
labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small')
3.4 设置非线性刻度
在一些情况下,我们对于坐标轴设置要用非线性的形式,如科学计数法、logit格式等,可以用plt.scale()来设置。
代码语言:javascript复制plt.scale('linear')
plt.scale('logit')
3.5 设置坐标轴位置
这个相对比较复杂,可以认为是坐标轴设置中最复杂的操作了。开始之前还是先科普一个方法,plt.gca()是获取当前的坐标轴选项,获取之后可以进行各种操作了。设置坐标轴位置的函数是plt.spine(),其实就是设置四周的边框。这个比较不好理解,举个相对比较全的例子
代码语言:javascript复制import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-5, 5, 100)
y1 = 0.5 * x
y2 = x * x
plt.figure()
plt.xlabel('X axis...')
plt.ylabel('Y axis...')
#以上为常规操作,就是设置基础数据
ax = plt.gca() # get current axis 获得坐标轴对象以下以ax为基础进行操作
ax.spines['right'].set_color('none') #隐藏掉右边框线
ax.spines['top'].set_color('none') #隐藏掉左边框线
ax.xaxis.set_ticks_position('bottom') #设置坐标轴位置
ax.yaxis.set_ticks_position('left') #设置坐标轴位置
ax.spines['bottom'].set_position(('data', 0)) #绑定坐标轴位置,data为根据数据自己判断
ax.spines['left'].set_position(('data', 0))
plt.plot(x, y1, linestyle='--')
plt.plot(x, y2)
plt.show()
最后画出来的图是这样的:
坐标轴设置
3.6 设置刻度线
刻度线是坐标轴上的小横线或者小竖线,基本语法是tick_params(axis=’both’, **kwargs),参数比较多,具体不列出来了,想看的话参考这篇文章https://blog.csdn.net/ggg_001/article/details/81486844。
3.7 设置网格线
网格线就是图中间的线,可以认为设置有无,线形,颜色等,基本用法是plt.grid。
代码语言:javascript复制plt.grid(b, which, axis, color, linestyle, linewidth, **kwargs)
效果图是这样的。
设置网格线
4.设置xy轴的标题
正如之前所说,可以用plt和ax设置,这个比较简单。直接看案例吧:
代码语言:javascript复制fig,ax = plt.subplots()
ax.plot(np.random.randn(1000).cumsum())
ax.set_xlabel('iteration',fontsize=15)
plt.ylabel('value',fontsize=15)
效果是这样的:
xy轴名字设置
5.设置数据标签
数据标签是指图上相应位置上显示的数字,这个目前还没有一个明确的函数或者参数可以直接设置显示,需要使用text进行文字的标注。 语法是这样子的:
代码语言:javascript复制text(x,y,string,fontsize=15,verticalalignment="top",horizontalalignment="right")
其中,xy是要标注的x轴和y轴坐标,string是要显示的文字。其他还有很多参数,一般我们用不到,用到的时候可以自行百度。 如果你要标注所有的数据用一个循环控制,如果不是要标注所有的数据可以一个个关键点标注。 看个案例
代码语言:javascript复制x_data = ['2012', '2013', '2014', '2015', '2016', '2017', '2018']
y_data = [58000, 60200, 63000, 71000, 84000, 90500, 107000]
y_data2 = [52000, 54200, 51500,58300, 56800, 59500, 62700]
# 绘图
plt.bar(x=x_data, height=y_data, label='C语言基础', color='steelblue', alpha=0.8)
plt.bar(x=x_data, height=y_data2, label='Java基础', color='indianred', alpha=0.8)
# 下面是设置标签, 100意识是在正常y值上方100个单位显示
for x, y in enumerate(y_data):
plt.text(x, y 100, '%s' % y, ha='center', va='bottom')
for x, y in enumerate(y_data2):
plt.text(x, y 100, '%s' % y, ha='center', va='top')
更高级的用法还可以设置箭头和带边框文本框,具体大家可以自己探索,以下给出用法:
代码语言:javascript复制arrowprops #箭头参数,参数类型为字典dict
width the width of the arrow in points 点箭头的宽度
headwidth the width of the base of the arrow head in points 在点的箭头底座的宽度
headlength the length of the arrow head in points 点箭头的长度
shrink fraction of total length to ‘shrink’ from both ends 总长度为分数“缩水”从两端
facecolor 箭头颜色
bbox给标题增加外框 ,常用参数如下:
boxstyle方框外形
facecolor(简写fc)背景颜色
edgecolor(简写ec)边框线条颜色
edgewidth边框线条大小
bbox=dict(boxstyle='round,pad=0.5', fc='yellow', ec='k',lw=1 ,alpha=0.5) #fc为facecolor,ec为edgecolor,lw为lineweight
6.设置注释
设置注释有两种方法,分别为text何annotate,其实这两种方式都差不多,一般结合使用,经常用annotation编辑带箭头的标注,二者的语法有点差距。 text上面已经介绍过了,不多说了,主要说说annotate。 annotate的基础语法是
代码语言:javascript复制ax.annotate('local max', xy=(3, 1), xycoords='data',
xytext=(0.8, 0.95), textcoords='axes fraction',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='right', verticalalignment='top' )
其中localmax是要标注的内容,xy是坐标,xytext是文字位置,textcoords是文字坐标系,就用默认的就行,arrowprops是箭头设置。 来看案例。
代码语言:javascript复制fig, ax = plt.subplots()
t = np.arange(0., 5., 0.01)
s = np.cos(2 * np.pi * t)
ax.plot(t, s, lw=2) # lw表示线条宽度
ax.annotate(‘local max’, xy=(2, 1), xytext=(3, 1.5), arrowprops=dict(facecolor=‘black’))
ax.set_ylim(-2, 2) plt.show()
效果是这样子的:
annotate使用示意
7.设置图表标题
这个其实和设置xlabel还有ylabel是一样的,只不过是用title取代了xlabel和ylabel。基本用法就是plt.title(),ax.set_title(),也可以设置字体大小。
8.设置图表间隔
这个是这篇文章的最后一个知识点,主要是为了防止图像堆叠在一起不美观,因此需要对图表的间隔进行设置。
8.1 设置坐标轴的刻度
设置坐标轴的间隔,需要引入MultipleLocator这个函数,具体操作如下:
代码语言:javascript复制x_values=list(range(11))
y_values=[x**2 for x in x_values]
plt.plot(x_values,y_values,c='green')
plt.title('Squares',fontsize=24)
plt.tick_params(axis='both',which='major',labelsize=14)
plt.xlabel('Numbers',fontsize=14)
plt.ylabel('Squares',fontsize=14)
#设置x和y轴的位置间隔
x_major_locator=MultipleLocator(1)
y_major_locator=MultipleLocator(10)
ax=plt.gca()
ax.xaxis.set_major_locator(x_major_locator)
ax.yaxis.set_major_locator(y_major_locator)
plt.xlim(-0.5,11)
plt.ylim(-5,110)
plt.show()
效果如下:
设置坐标轴刻度
8.2 设置子图间隔
首先是设置默认的间隔和空白,用plt.tight_layout() 。 如果要对子图间隔进行细调,用plt.subplots_adjust(wspace =0, hspace =0)。