从零开始利用Matplotlib作图举例

举一反三

Matplotlib文档繁杂,图片的属性众多,和学习linux一样,不太可能记住几千条命令,怎么办呢?更合理的方法是掌握学习方法,学会读文档的方法,有了钓鱼的方法,勤加苦练,还怕吃不到鱼么?

饼状图举例

从没有画过饼状图,现在手里有数据,想做一个饼状图,如何处理呢?

找到资料

官方文档的资料足够丰富,Data103数据科学课的时候还在依靠搜索引擎和Stack Overflow。其实文档足以。像Matplotlib学习指南一样对官方文档做完充分了解后,面对新的图形,只要找到对应的内容学习即可:

  • pyplot找到绘图方法pie:这里对pie涉及到的参数有详细说明。
  • Gallery找到饼状图案例:结合案例,更容易理解文档中的指标作用。

代码实现

已有的数据如下:

名称 数据(箱)
销量(已完成) 209433
销量(未完成) 10116

Jupyter Notebook实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 模仿官网给出的案例
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']
explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')

plt.pie(sizes, explode=explode, labels=labels, colors=colors,
autopct='%1.1f%%', shadow=True, startangle=90)
# Set aspect ratio to be equal so that pie is drawn as a circle.
plt.axis('equal')

# 初步实现自己的饼图
label = 'sale','unsale'
size = [209433,10116]
color = ['yellowgreen','lightcoral']
explode = (0, 0.1) # only "explode" the 2nd slice (i.e. 'Hogs')
plt.pie(size, explode=explode, labels=label, colors=color,
autopct='%1.1f%%', pctdistance = 0.8,shadow=False, startangle=90)
plt.axis('equal')

变量分析

按图索骥并不困难,下一步更为关键,逐一了解官方文档中给出的变量含义,并且根据这个内容来调整自己的图像,同时建立全新的知识体系。文档开篇久说明了pie函数的所有变量,并且给出了示例,对变量的默认值情况。

1
2
3
4
5
6
7
8
matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, hold=None, data=None)

pie(x, explode=None, labels=None,
colors=('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'),
autopct=None, pctdistance=0.6, shadow=False,
labeldistance=1.1, startangle=None, radius=None,
counterclock=True, wedgeprops=None, textprops=None,
center = (0, 0), frame = False )

Make a pie chart of array x. The fractional area of each wedge is given by x/sum(x). If sum(x) <= 1, then the values of x give the fractional area directly and the array will not be normalized. The wedges are plotted counterclockwise, by default starting from the x-axis.

说明了饼图的设计逻辑,而下文的Keyword arguments更是对每一个变量的使用说的清清楚。看不懂?最好的办法是动手实践。

autopct: [ None | format string | format function ]
If not None, is a string or function used to label the wedges with their numeric value. The label will be placed inside the wedge. If it is a format string, the label will be fmt%pct. If it is a function, it will be called.

以autopct变量举例,文档只说明了用’fmt%pct’格式来写变量。案例中有更明确的方法是autopct='%1.1f%%',试着挑战参数后发现这里会改变在饼图中显示的比例数字的小数点位数,问题解决。

用类似的方法很快可以建立起自己的知识结构,并且对其他的matplotlib作图不再担心。

二次函数案例

作图要求

上面的示例是一个完整的图例类型,如果是一个已知的图像的某些属性不了解怎么办呢?下面用二次函数的案例举例,数据给定如下:

1
2
3
4
# 定义数据
x =np.linspace(-np.pi,np.pi,256)
s = np.sin(x)
c = np.cos(x)

要求作出如下的图形并给出完成标准:

  • 画布大小为:10*6
  • 体现出如下图的坐标系,并去掉边框
  • 数字坐标改为用$\pi$的方式表达,并且仅留下图上的坐标个数
  • 给出自己任意指定的点,并用文字(中英文、公式均可以)、箭头注释

作图步骤

首先导入基础包,其中魔法函数%matplotlib inline可方便Jupyter Notebook作图时图片仅在notebook中展示。

1
2
3
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

画出基本图形,在此基础上进行后续的设置。

1
2
3
4
# 画出基本图形
fig,ax = plt.subplots(figsize = (10,6))
ax.plot(x,s)
ax.plot(x,c)

通过’spine’设置周围的四条边框,调整到对应的位置或者隐藏,形成坐标,并且扩大坐标的范围,可以完整融入图片。

1
2
3
4
5
6
7
8
# 设置坐标轴
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.tick_params(axis='x',top = 'off')
ax.tick_params(axis='y',right = 'off')
ax.spines['left'].set_position(('data',0))
ax.spines['bottom'].set_position(('data',0))
ax.set_ylim(s.min()*1.1,s.max()*1.1);

增加对应的注释内容,辅助线等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 增加注释(箭头、点)、辅助线
# sin
ax.scatter(np.pi/2,np.sin(np.pi/2),20)
ax.annotate(r'$\sin(\frac{\pi}{2}):top\ point$',
xy=(np.pi/2,np.sin(np.pi/2)),
xytext=(3,1),fontsize=20,
arrowprops=dict(arrowstyle='->',connectionstyle='arc3,rad=.2'))
ax.plot((np.pi/2 , np.pi/2),(0,np.sin(np.pi/2)),color = 'black',lw=0.5,ls='--')

# cos
ax.scatter(np.pi*2/3,np.cos(np.pi*2/3),20)
ax.annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$',
xy=(np.pi*2/3,np.cos(np.pi*2/3)),
xytext=(3,-0.5),fontsize=20,
arrowprops=dict(arrowstyle='->',connectionstyle='arc3,rad=.2'))

修改刻度说明

1
2
ax.set_xticks( [-np.pi, -np.pi/2, 0, np.pi/2, np.pi])
ax.set_xticklabels((r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'));

增加英文注释,完成所有的操作,效果如题目要求的图片。

1
2
# 注释
ax.annotate('map',xytext=(-3,0.75),fontsize=20,xy=(0,1));

理解体会

和上一个案例类似,开始作图前我并不了解相关的函数应用,甚至在找到了案例之后,发现许多的函数和案例中的不一致,无法直接生效。解决这个问题的方法和上个案例也是类似的:通过案例了解可能遇到的函数,到官方文档找到对应的函数或者对应的子模块通过文档不断摸索。
探索的结果很丰富,除了作出图形之外,进一步理解了Matplotlib中“面向对象”的作图方式,每一个元素都可以理解为一个对象,对象之间是有继承关系的。我们在不断的从一个对象返回另一个对象,在另一个对象的自身方法进行参数设置。慢慢会对理解下图有一点感觉了:

本次案例对作图中的’spines‘、’xticks\yticks‘、’xlim\ylim‘、’xaxis\yaxis‘、’xticklabels\yticklable‘以及注释的使用会有深入的理解,这里不多说,希望大家可以通过上面的方法自行探索,祝愿大家收获满满。

彩蛋

代码地址:big pie|sine & cosine function
在线查看地址:big pie|sine & cosine function

在上述代码地址里,仔细找找会发现其他的我的探索内容,希望得你有帮助:)

声明: 本文转载需标明出处,禁止用于商业目的。

ChangeLog

161206 新建
161207 发布