这是“简洁优雅的Matplotlib可视化”栏目的第 6 篇文章!
这是一篇姗姗来迟的可视化教程。
如果前几期推送帮助你掌握了使用Matplotlib绘图的基本技巧。那么,从这期开始,我希望你能精通这项技能。实际上,图片的高级配置方法贯穿整个Matplotlib知识体系,往期的教程中我们也根据实际的需要,使用到了一部分图片的高级配置方法。为了更系统地学习这些配置图片的技巧,一起进入下面的干货实践教程!
一般地,Matplotlib会根据你的图形选择最适合的坐标轴上下限。但是,自定义坐标轴上下限可能会更好。调整坐标轴上下限最基础的方法是plt.xlim()和plt.ylim():
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x))
plt.xlim(-1, 11)
plt.ylim(-1.5, 1.5)
如果想要让坐标轴逆序显示,那么也可以逆序设置坐标轴刻度值:
plt.plot(x, np.sin(x))
plt.xlim(11, -1)
plt.ylim(1.5, -1.5)
另一个设置坐标轴上下限的方法是plt.axis()。通过传入[xmin, xmax, ymin, ymax]对应的值,plt.axis()方法可以让你用一行代码设置x和y的限值:
plt.plot(x, np.sin(x))
plt.axis([-1, 11, -1.5, 1.5])
此外,plt.axis()还可以按照图形的内容自动收紧坐标轴,不留空白区域:
plt.plot(x, np.sin(x))
plt.axis('tight')
还可以实现更高级的配置,例如让屏幕上显示的图形分辨率为1:1,即x轴单位长度与y轴的单位长度相等:
plt.plot(x, np.sin(x))
plt.axis('equal')
更多的plt.axis()方法设置坐标轴上下限和其他更多功能,请参考plt.axis()程序文档。
设置图形标签主要包括对图形标题和坐标轴标题的设置,快速设置方法如下:
plt.plot(x, np.sin(x))
plt.title('A Sine Curve')
plt.xlabel('x')
plt.ylabel('sin(x)')
(1)主次坐标刻度
Matplitlib拥有绘制次要坐标轴的功能。例如,绘制一个对数坐标的方法如下:
import matplotlib.pyplot as plt
import numpy as np
ax = plt.axes(xscale='log', yscale='log')
(2)隐藏刻度与标签
隐藏刻度与坐标是比较常用的刻度/标签格式化操作。可以通过plt.NullLocator()和plt.NullFormatter()实现,如下所示:
ax = plt.axes()
ax.plot(np.random.rand(50))
ax.xaxis.set_major_locator(plt.NullLocator())
ax.yaxis.set_major_formatter(plt.NullFormatter())
(3)增减刻度数量
在不同图形中,默认刻度可能过于疏松或拥挤,对图形美观和展示效果有所影响。因此,适当地增减刻度数量成为需要。我们可以用plt.MaxNLocator()来解决这个问题(请注意大小写),通过它可以设置最多显示多少刻度。根据设置的最多刻度数量,Matplotlib会自动为刻度安排恰当的位置。
ax = plt.axes()
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x))
ax.xaxis.set_major_locator(plt.MaxNLocator(6))
ax.yaxis.set_major_locator(plt.MaxNLocator(5))
图中设置横坐标为6个刻度,纵坐标为5个刻度。
(4)其他刻度格式
在默认刻度格式的基础上,我们还可能有更个性化的需求。例如,绘制正弦、余弦曲线时,如果横坐标的刻度和网格线能正好落在π的倍数上,会显得更加自然。这时可以通过设置MultipleLocator参数来实现,
ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2))
ax.yaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4))
然而,这些刻度虽然是π的倍数,但是用小数表示圆周率不够直观。因此,我们可以用刻度格式生成器来修改。用一个自定义函数设置不同刻度标签的显示,并用plt.FuncFormatter()来实现。
def format_func(value, tick_number):
# 找到pi/2的倍数
N = int(np.round(2 * value / np.pi))
if N == 0:
return '0'
elif N == 1:
return r'$pi/2$'
elif N == 2:
return r'$pi$'
elif N % 2 > 0:
return r'${0}pi/2$'.format(N)
else:
return r'${0}pi$'.format(N // 2)
ax.xaxis.set_major_formatter(plt.FuncFormatter(format_func))
除了数字类型的坐标刻度,我们还会经常遇到文本类型的坐标刻度。那么,如何显示这种类型的刻度呢?用一个plt.xticks()函数就能完成啦!为此,我在篇末补充了一个“北京地铁进站量”的案例,案例中的横坐标就是用文本格式表示的时间。案例中用到的数据是每隔五分钟统计的地铁进站量。
下面直接来看代码:
# 调用程序包
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 绘图风格
plt.style.use('seaborn-notebook')
# 创建图像
fig = plt.figure()
# 创建坐标轴
ax = plt.axes()
# 读取数据
data = pd.read_csv('metro_arrivel.csv')
weekend_arrivel, workday_arrivel = data['weekend'], data['workday']
# 绘制进站人数线形图
plt.plot(range(288), weekend_arrivel, '--k',label = 'weekend',linewidth = 1)
plt.plot(range(288), workday_arrivel, '-k',label = 'workday',linewidth = 1)
plt.ylabel('bus')
# 配置x轴刻度
x = ['0:00','4:00','8:00','12:00','16:00','20:00','24:00']
plt.xticks(range(0,289,48),x)
# 配置图形标签和图例
plt.title("Number of metro arrivals")
plt.xlabel('time')
plt.ylabel('population')
plt.legend()
plt.show()
下图为脚本运行的结果。
以上就是本期的全部内容啦!
与往期精彩内容相关链接:
王婷:简洁优雅的Matplotlib可视化 | mpl基础zhuanlan.zhihu.com 王婷:简洁优雅的Matplotlib可视化 | 绘制论文曲线图zhuanlan.zhihu.com 王婷:简洁优雅的Matplotlib可视化 | 大数据看北京城市轨道交通运营zhuanlan.zhihu.com 王婷:简洁优雅的Matplotlib可视化 | 经纬度坐标系转换zhuanlan.zhihu.com 王婷:简洁优雅的Matplotlib可视化 | 绘制公共交通节点分布二维直方图zhuanlan.zhihu.com我们是一个有灵魂的团队,坚持探索,致力于分享交流学习经验。接下来的两期本栏目推送还会继续为大家讲解图片的高级配置方法,想学习更多编程知识的小伙伴就请持续关注我们吧~
本文首发于微信公众号"交通科研Lab",更多资料和推送请扫码关注!