画出这张官方神图,你的Matplotlib就毕业了!

早起Python

共 5007字,需浏览 11分钟

 ·

2021-01-19 00:20

大家好,我是早起。

在昨天的文章人人都能看懂的Matplotlib绘图原理中,我们对Matplotlib的绘图机制进行了讲解,在弄清楚plt.xxxxax.xxxx中plt和ax区别之后,本文继续讲解xxxx究竟是什么。

现在我们应该知道Matplotlib绘图其实很简单,不就是弄一块画布,然后往这块画布上添加我们要的图形,最后就是进行修饰

如何添加画布/绘图区域已经讲过,如何添加图形,看我发的各种可视化图鉴就行了,而最需要花时间的就是对初步成型的图案进行修饰,先来看一张来自官方文档的图

我们可以看到,其实无非就是设置标题、图例、坐标轴、标记点等操作,这部分看起来简单,不过有时因为数据的原因,想要调整到一个合适的样式,是需要花费心思的

但不论如何,能用到的Matplotlib修饰操作就这么多,本文将按照上图的顺序带大家手把手的绘制出图中的每一部分,希望以这种方式对常用的修饰语法进行讲解

如果你能独立的,简单思考查询后能将这张图画出来,那么matplotlib基本就算毕业了!

请注意,由于篇幅原因,本文对大多数方法仅作简单介绍,因此并不适合作为速查手册使用,详细的matplotlib各组件设置,点击菜单栏查看专题文章。

标题

首先是标题,如果是使用plt.xxxx那么就用plt.title(),如果使用ax.xxxx可以使用ax.set_title(),现在我们把标题做成官方文档的样式,更多标题的修改方法可以查看matplotlib标题设置

plt.rc('font',family='Avenir'
plt.figure(figsize = (8,7), dpi=100)
plt.title("Anacomy of a figure",fontsize = 20,fontweight='heavy')
plt.show()

刻度

搞定了标题,下一步就是刻度了,根据我的了解,因为自己的数据原因,大多需要对刻度进行调整,但是修改刻度,相对复杂一点,所以很多人多会卡在刻度设置上。

其实设置刻度确实体育达标复杂,从图中我们可以看到又分为主、副刻度,再算上xy轴,一共就是4个刻度需要设置。

因为比较复杂,所以建议使用ax.xxxx进行设置。这里我们首先需要把刻度读取出来,先使用的语法为

ax = plt.gca()

意思是Get Current Axes,获得当前绘图区域,接下来使用ax.set_xlim设置x坐标轴范围,等同于plt.xlim(),y轴同理

ax.set_xlim(0,4)
ax.set_ylim(0,4)

现在坐标轴范围搞定了,接下来就是比较复杂的刻度调整,我们可以看到,从官方示例图中,我们可以发现在matplotlib中,一个坐标轴,分为主副两个刻度

关于坐标轴刻度的设置详情,可以参考matplotlib刻度设置文章,我们先来设置x、y轴的主刻度,只需要将间隔调整为1即可,通过修改locator类完成

xmajorLocator   = MultipleLocator(1)
ax.xaxis.set_major_locator(xmajorLocator)

ymajorLocator   = MultipleLocator(1)
ax.yaxis.set_major_locator(ymajorLocator)

主刻度的调整就完成了,接下来是副刻度的调整,我们需要将x轴副刻度以0.25为单位分开,并显示数值,y轴副刻度同样为0.25但是不显示数值,以x轴为例,调整副刻度及数值显示可以通过·ax.xaxis.set_minor_formatterax.yaxis.set_minor_locator`实现

xminorLocator   = MultipleLocator(0.25)
ax.xaxis.set_minor_locator(xminorLocator)

yminorLocator   = MultipleLocator(0.25)
ax.yaxis.set_minor_locator(yminorLocator)

xminorFormatter = FormatStrFormatter('%0.2f')
ax.xaxis.set_minor_formatter(xminorFormatter)

可以看打,现在的主副刻度已经做的差不多了,但是官方示例图中的刻度线更长一点,对刻度线进行调整可以使用tick_params

tick_params(which='major',length=8)
tick_params(which='minor',length=4)

网格线

刻度线搞定之后,下一步添加网格线,我们可以使用ax.xaxis.gridax.yaxis.grid分别对指定x轴和y轴的网格线,可选参数非常多,详见matplotlib网格线设置

在这里,我们按照官方示例图的样式,两个坐标轴都添加主刻度网格线,并使用,linestyle = (0,(10,5))对线性进一步调整

ax.xaxis.grid(True, which='major',linestyle = (0,(8,4))) 
ax.yaxis.grid(True, which='major',linestyle = (0,(8,4))) 

现在看我们的图是不是和示例图有几分相似了呢👇

坐标轴文字

现在继续给坐标轴添加文字,这部分就比较简单了,当然我也写了详细的文档,这里使用ax.set_xlabel或者plt.xlabel都可以,我们使用如下代码

ax.set_xlabel("X axis label",fontsize = 12)
ax.set_ylabel("Y axis label",fontsize = 12)

添加图像

现在对于画布的修饰部分,基本就结束了,下面添加图形,示例图中一共有两个折线图和一个散点图,我们拟合部分数据并制作进行,这里使用ax.plotax.scatter分别制作折线图和散点图,不知道怎么画的可以看我之前发的各种图鉴

x = list(np.arange(0.5,3.3,0.1))
y1 = [-0.04658*i**3+0.5494*i**2-1.3151*i + 1.415 for i in x]
ax.plot(x,y1,color = 'red',alpha = 0.7, linewidth=2.3)

x = list(np.arange(0.5,3.5,0.1))
y2 = [0.1545*i**3-0.799*i**2+0.4316*i + 3.744 for i in x]
ax.plot(x,y2,color = 'blue',alpha = 0.7, linewidth=2.3)

ax.scatter(A, B,marker = 'o',color="w",edgecolors='black')

现在,是不是感觉非常相似了!我们继续。

添加图例

整体还差最后一个图例就完成了,添加图例比较简单,使用plt.legend()或者ax.legend()都可以实现,不过需要在绘图是添加label标签才行

添加文字

其实图像主体部分已经完成了,但是原来的示例图中还有一些蓝色的文字,我们也添加进来,其实用到的就是plt.text(),也是非常常见的一个用法,我在matplotlib添加注释中有详细讲解,本文这里就是根据坐标添加文字,部分代码如下

ax.text(2.9,2.7,"Gird",family = "DejaVu Sans",fontsize = 11,color = 'blue',weight='heavy')
ax.text(3.45,3.45,"Legend",family = "DejaVu Sans",fontsize = 10,color = 'blue',weight='heavy')
ax.text(1.5,3.85,"Title",family = "DejaVu Sans",fontsize = 11,color = 'blue',weight='heavy')
ax.text(-0.25,3.75,"Major tick",family = "DejaVu Sans",fontsize = 10,color = 'blue',weight='heavy')
ax.text(-0.25,3.25,"Minor tick",family = "DejaVu Sans",fontsize = 10,color = 'blue',weight='heavy')
ax.text(-0.45,2.75,"Major tick label",family = "DejaVu Sans",fontsize = 10,color = 'blue',weight='heavy')
ax.text(0.12,-0.5,"Minor tick label",family = "DejaVu Sans",fontsize = 10,color = 'blue',weight='heavy')

其中箭头是通过ax.arrow做出来的,使用方法和ax.text一样通过调整坐标控制

ax.arrow(3.3,0.41,-0.15,-0.33,ec='blue',head_width=0.04)
ax.arrow(3.6,0.41,0.32,-0.15,ec='blue',head_width=0.04)

现在我们的画的图和官方文档的示例图已经差不多一样了,唯一就是差了在不同组件旁的类似放大镜效果的图片。

添加自定义图片

最后,让我们和官方文档一样,在注释的位置添加指定图片,来达到一种放大的感觉。

在Matplotlib中,添加图片的方法有多种,这里我们选择使用ax.add_artist(),详细讲解在后续文章中更新,简单来说就是打开一张图片,之后根据坐标添加到我们想要的位置就行了。

以左上角Major tick的圆为例,我们使用OffsetImage打开一张图片

arr_lena = mpimg.imread('/Users/liuhuanshuo/Desktop/WechatIMG2278.png')
imagebox = OffsetImage(arr_lena, zoom=0.38)

之后使用a1 = AnnotationBbox(imagebox, (0, 4), frameon = False)设置图片位置,最后使用ax.add_artist(a1)就能添加一个空心圆在左上角,之后如法炮制就可以了。

最终我们制作的仿官方文档效果图如下

是不是可以以假乱真呢,感兴趣的读者可以自己尝试绘制一下。长按扫描下方二维码关注「可视化图鉴」在后台回复0117可以获得我使用Notebook进行学习、复现。

最后早起想说一下,其实这篇文档本来的标题是「一篇文章带你搞定Matplotlib中组件设置」,后来写着写着,发现一篇文章根本搞不定,可能光一个plt.tltle()就有很多可以说道的,所以我就希望通过绘制官方示例图,带大家了解Matplotlib中绘图的基本流程和常见方法使用。

当然每一个组件设置,我都写了详细的文档指导你修改,所以如果你对文章任何一个部分感兴趣,都可以查看对应设置的文章来进一步学习!

最后推荐一本数据可视化的R语言数据分析与可视化从入门到精通本书是关于R语言数据分析与可视化从入门到精通的指南,较为全面地介绍了R语言的常用功能和方法,且紧密围绕实际应用展开。例如,从R语言的发展历史到R语言的一些常用函数,从数据管理到数据分析,从基础统计到高级统计,从图形生成到图形优化,从分步应用到综合应用等。通过本书,读者可以掌握R语言的基本功能和原理,并进一步深入学习更多的相关知识。

为了回馈粉丝,早起也送几本给大家。

点击阅读原文,关注公众号「可视化图鉴」,按照文中规则进行留言,即有机会包邮获赠图书!

浏览 18
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报