Matplotlib is hiring a Research Software Engineering Fellow! See discourse for details. Apply by January 3, 2020
本教程旨在使用matplotlib显示单个可视化的开始、中间和结束。我们将从一些原始数据开始,最后保存一个自定义可视化的图形。在此过程中,我们将尝试使用matplotlib突出显示一些整洁的特性和最佳实践。
注解
本教程基于 this excellent blog post 作者:克里斯·莫菲特。它由ChrisHoldgraf转化为本教程。
Matplotlib有两个接口。第一个是面向对象(OO)接口。在这种情况下,我们使用 axes.Axes
为了在 figure.Figure
.
第二种是基于Matlab,使用基于状态的接口。它被封装在 pyplot
模块。见 pyplot tutorials 要更深入地了解Pyplot接口。
大多数术语都是直截了当的,但要记住的是:
我们称之为直接从轴进行绘图的方法,这使我们在自定义绘图时更加灵活和强大。
注解
通常,尝试在Pyplot接口上使用面向对象的接口。
我们将使用从中派生本教程的文章中获得的数据。它包含许多公司的销售信息。
# sphinx_gallery_thumbnail_number = 10
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
data = {'Barton LLC': 109438.50,
'Frami, Hills and Schmidt': 103569.59,
'Fritsch, Russel and Anderson': 112214.71,
'Jerde-Hilpert': 112591.43,
'Keeling LLC': 100934.30,
'Koepp Ltd': 103660.54,
'Kulas Inc': 137351.96,
'Trantow-Barrows': 123381.38,
'White-Trantow': 135841.99,
'Will LLC': 104437.60}
group_data = list(data.values())
group_names = list(data.keys())
group_mean = np.mean(group_data)
这些数据自然地被视为一个条形图,每组一个条形图。为了使用面向对象的方法实现这一点,我们首先将生成 figure.Figure
和 axes.Axes
. 这个图形就像一张画布,坐标轴是画布的一部分,我们将在画布上进行特殊的可视化。
注解
图形上可以有多个轴。有关如何执行此操作的信息,请参见 Tight Layout tutorial .
fig, ax = plt.subplots()
现在我们有了一个轴实例,我们可以在上面绘图。
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
Matplotlib中有许多样式可供选择,以便根据需要定制可视化效果。要查看样式列表,我们可以使用 pyplot.style
.
print(plt.style.available)
出:
['bmh', 'dark_background', 'seaborn-paper', 'seaborn-deep', 'seaborn-dark', 'seaborn-pastel', '_classic_test', 'Solarize_Light2', 'seaborn-white', 'ggplot', 'fast', 'classic', 'seaborn', 'grayscale', 'seaborn-whitegrid', 'tableau-colorblind10', 'seaborn-poster', 'seaborn-dark-palette', 'seaborn-darkgrid', 'fivethirtyeight', 'seaborn-bright', 'seaborn-talk', 'seaborn-colorblind', 'seaborn-notebook', 'seaborn-muted', 'seaborn-ticks']
可以使用以下选项激活样式:
plt.style.use('fivethirtyeight')
现在,让我们重新绘制上面的图,看看它是什么样子的:
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
样式控制许多内容,如颜色、线条宽度、背景等。
现在我们有了一个我们想要的总体外观的情节,所以让我们对它进行微调,以便它可以打印。首先,让我们旋转X轴上的标签,使它们显示得更清楚。我们可以通过 axes.Axes.get_xticklabels()
方法:
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
如果我们想同时设置多个项目的属性,使用 pyplot.setp()
功能。这将获取matplotlib对象的列表(或多个列表),并尝试为每个对象设置一些样式元素。
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
看起来像是把底部的一些标签剪掉了。我们可以告诉matplotlib自动为我们创建的图形中的元素腾出空间。为此,我们将设置 autolayout
我们的RCPARAM的价值。有关使用RCPARAM控制绘图的样式、布局和其他功能的详细信息,请参见 使用样式表和RCPARAM自定义Matplotlib .
plt.rcParams.update({'figure.autolayout': True})
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
接下来,我们将向绘图添加标签。要使用OO接口完成此操作,我们可以使用 axes.Axes.set()
方法设置此轴对象的属性。
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
title='Company Revenue')
我们也可以使用 pyplot.subplots()
功能。我们可以用 figsize
克瓦格
注解
当numpy中的索引遵循形式(行、列)时,figsize kwarg遵循形式(宽度、高度)。这遵循可视化的惯例,不幸的是,这与线性代数的惯例不同。
fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
title='Company Revenue')
对于标签,我们可以使用 ticker.FuncFormatter
班级。下面我们将定义一个以整数作为输入并返回字符串作为输出的函数。
def currency(x, pos):
"""The two args are the value and tick position"""
if x >= 1e6:
s = '${:1.1f}M'.format(x*1e-6)
else:
s = '${:1.0f}K'.format(x*1e-3)
return s
formatter = FuncFormatter(currency)
然后我们可以将这个格式化程序应用于绘图上的标签。为此,我们将使用 xaxis
我们轴心国的属性。这可以让您在绘图的特定轴上执行操作。
fig, ax = plt.subplots(figsize=(6, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
title='Company Revenue')
ax.xaxis.set_major_formatter(formatter)
可以在同一个实例上绘制多个绘图元素 axes.Axes
. 要做到这一点,我们只需要调用轴对象上的另一个绘图方法。
fig, ax = plt.subplots(figsize=(8, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
# Add a vertical line, here we set the style in the function call
ax.axvline(group_mean, ls='--', color='r')
# Annotate new companies
for group in [3, 5, 8]:
ax.text(145000, group, "New Company", fontsize=10,
verticalalignment="center")
# Now we'll move our title up since it's getting a little cramped
ax.title.set(y=1.05)
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
title='Company Revenue')
ax.xaxis.set_major_formatter(formatter)
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
fig.subplots_adjust(right=.1)
plt.show()
现在我们对我们的情节的结果感到满意,我们想把它保存到磁盘上。我们可以在matplotlib中保存许多文件格式。要查看可用选项列表,请使用:
print(fig.canvas.get_supported_filetypes())
出:
{'ps': 'Postscript', 'eps': 'Encapsulated Postscript', 'pdf': 'Portable Document Format', 'pgf': 'PGF code for LaTeX', 'png': 'Portable Network Graphics', 'raw': 'Raw RGBA bitmap', 'rgba': 'Raw RGBA bitmap', 'svg': 'Scalable Vector Graphics', 'svgz': 'Scalable Vector Graphics', 'jpg': 'Joint Photographic Experts Group', 'jpeg': 'Joint Photographic Experts Group', 'tif': 'Tagged Image File Format', 'tiff': 'Tagged Image File Format'}
然后我们可以使用 figure.Figure.savefig()
以便将图形保存到磁盘。请注意,我们将在下面显示几个有用的标志:
transparent=True
如果格式支持,则使保存的图形的背景透明。dpi=80
控制输出的分辨率(每平方英寸点数)。bbox_inches="tight"
使图形的边界适合我们的绘图。# Uncomment this line to save the figure.
# fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")
脚本的总运行时间: (0分1.533秒)