本教程旨在展示使用Matplotlib的单个可视化的开始、中间和结束。

我们将从一些原始数据开始,最后保存一个定制的可视化图形。

在此过程中,我们尝试使用Matplotlib来突出一些整洁的特性和最佳实践。


注意:本教程基于克里斯·莫菲特这篇优秀的博客文章。它被克里斯·霍德格拉夫转化为本教程。


关于面向对象的API与Pyplot的说明

Matplotlib有两个接口,第一个是面向对象(OO)接口。在本例中,我们使用axes.ax的一个实例来呈现图形实例上的可视化。

第二部分基于MATLAB,采用基于状态的接口,封装在pyplot模块中。更深入地了解pyplote界面,请参阅pyplot教程。

大多数术语都是直截了当的,但主要要记住的是:

  • 图形是可能包含一个或多个绘图区域的最终图像。
  • Axes表示一个单独的绘图区域(不要将"Axes"与“Axis”一词混淆,后者指的是绘图的坐标轴)。

我们调用直接从绘图区域进行绘图的方法,这给了我们更大的灵活性和更大的力量来定制我们的图像。


注意:通常情况下,尝试使用面向对象的接口而不是pyplot接口。


我们的数据

我们将使用来自于本教程的文章的数据,它包含了一些公司的销售信息。

import numpy as np
import matplotlib.pyplot as plt
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)
开始

这些数据自然被可视化为一个条形图,每个组有一个bar。为了使用面向对象的方法来实现这一点,我们首先生成一个图形实例:图形和绘图区域。图形就像一个画布,而绘图区域是画布的一部分,我们将在其中进行一个特定的可视化。


注意:图形上可以有多个绘图区域。有关如何执行此操作的信息,请参阅Tight Layout 教程。


fig, ax = plt.subplots()

python matpoltlib 多曲线_Text

现在我们有了一个Axes实例,我们可以在上面绘图。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)

python matpoltlib 多曲线_matplotlib_02

输出:

<BarContainer object of 10 artists>

控制样式

Matplotlib中有许多可用的样式,以便使您能够根据需要定制可视化。如果有一个样式列表,那么我们就可以参考使用。

print(plt.style.available)

输出:

['Solarize_Light2', '_classic_test_patch', 'bmh', 'classic', 'dark_background
↪', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn', 'seaborn-
↪bright', 'seaborn-colorblind', 'seaborn-dark', 'seaborn-dark-palette',
↪'seaborn-darkgrid', 'seaborn-deep', 'seaborn-muted', 'seaborn-notebook',
↪'seaborn-paper', 'seaborn-pastel', 'seaborn-poster', 'seaborn-talk',
↪'seaborn-ticks', 'seaborn-white', 'seaborn-whitegrid', 'tableau-colorblind10
↪']

可以使用以下命令激活样式:

plt.style.use('fivethirtyeight')

现在,让我们重新制作上面的图形,看看它看起来是怎样的:

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
plt.style.use('fivethirtyeight')

python matpoltlib 多曲线_Text_03

输出:

<BarContainer object of 10 artists>

样式控制许多东西,例如颜色、线宽、背景等。

定制图形

现在我们有了一个我们想要的总体外观的图形,所以让我们微调一下,这样它就可以打印了。首先,我们在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')

python matpoltlib 多曲线_python_04

输出:

[None, None, None, None, None, None, None, None, None, None, None, None, None,
↪ None, None, None, None, None]

看上去像是把底部的一些标签剪掉了。我们可以告诉Matplotlib在我们创建的图形中自动为元素腾出空间。为此,我们设置了rcParams的autolayout值。有关用rcParams控制图形的样式、布局和其他特性的表单信息,使用样式表和rcParams可以查看Matplotlib with style sheets and rcParams。

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')

python matpoltlib 多曲线_面向对象_05

输出:

[None, None, None, None, None, None, None, None, None, None, None, None, None,
↪ None, None, None, None, None]

接下来,我们将标签添加到绘图中。为了使用OO接口实现这一点,我们可以使用Artist.set()方法,设置此Axes对象的属性。

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')

python matpoltlib 多曲线_面向对象_06

输出:

[(-10000.0, 140000.0), Text(0.5, 0, 'Total Revenue'), Text(0, 0.5, 'Company'),
↪ Text(0.5, 1.0, 'Company Revenue')]

我们还可以使用pyplot.subplots()函数来调整这个绘图的大小。我们也可以figsize参数来调整绘图的大小。


注意:NumPy中的索引遵循表单(行、列),而图形大小的参数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')

python matpoltlib 多曲线_matplotlib_07

输出:

[(-10000.0, 140000.0), Text(0.5, 0, 'Total Revenue'), Text(0, 0.5, 'Company'),Text(0.5, 1.0, 'Company Revenue')]

For labels,we can specify custom formatting guidelines in the form of functions. Below we definea function that takes an integer as input,and returns a string as an output. When used with axis.set_major_formatter or Axis.set_minor_formatter, they will automatically create and usea ticker.FuncFormatter class.

对于标签,我们可以以函数的形式指定自定义格式指南。

下面我们定义了一个函数,它以一个整数作为输入,并返回一个字符串作为输出。当与Axis.set_major_formatterAxis.set_minor_formatter一起使用时,它们将自动创建和使用ticker.FuncFormatter类。

对于这个函数,x参数是原始的 tick 标签,pos是 tick 位置。我们将只使用x.here,但这两个参数都是必需的。

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

将此函数应用于绘图中的标签。要做到这一点,我们使用了axes的.xaxis属性ax.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(currency)

python matpoltlib 多曲线_matplotlib_08

组合多个可视化

在相同的绘图区域上绘制多个绘图元素是可能的。要做到这一点,我们只需调用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')
# 添加一条竖线,在这里我们设置函数调用中的样式
ax.axvline(group_mean, ls='--', color='r')
# 注释新公司
for group in [3, 5, 8]:
ax.text(145000, group, "New Company", fontsize=10,verticalalignment="center")
# 现在我们把标题调高,因为它有点拥挤
ax.title.set(y=1.05)
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',title='Company Revenue')
ax.xaxis.set_major_formatter(currency)
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
fig.subplots_adjust(right=.1)
plt.show()

python matpoltlib 多曲线_python_09

Saving our plot

保存图形

现在我们对我们的图形的结果感到满意,我们想把它保存到磁盘中。我们可以在Matplotlib中保存许多文件格式。要查看可用选项列表,请使用:

print(fig.canvas.get_supported_filetypes())

输出:

{'eps': 'Encapsulated Postscript', 'jpg': 'Joint Photographic Experts Group',
↪'jpeg': 'Joint Photographic Experts Group', 'pdf': 'Portable Document Format
↪', 'pgf': 'PGF code for LaTeX', 'png': 'Portable Network Graphics', 'ps':
↪'Postscript', 'raw': 'Raw RGBA bitmap', 'rgba': 'Raw RGBA bitmap', 'svg':
↪'Scalable Vector Graphics', 'svgz': 'Scalable Vector Graphics', 'tif':
↪'Tagged Image File Format', 'tiff': 'Tagged Image File Format'}

然后,我们可以使用figure.Figure.savefig()来将图形保存到磁盘中。请注意,我们在下面显示了一些有用的标志:

  • transparent=True 如果格式支持,则使保存的图形的背景透明。
  • dpi=80 控制输出的分辨率(每平方英寸点数)
  • bbox_inches=“tight” 使得图形符合界限

python matpoltlib 多曲线_python_10

# 保存图形
fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")