图的生命周期

本教程旨在使用Matplotlib显示单个可视化的开始、中间和结束。我们将从一些原始数据开始,最后保存一个自定义可视化的图形。在这一过程中,我们试图突出一些整洁的特性和使用Matplotlib的最佳实践。

注解

本教程基于 this excellent blog post 作者:克里斯·莫菲特。它由ChrisHoldgraf转化为本教程。

关于面向对象API与Pyplot的一点注记

Matplotlib有两个接口。第一个是面向对象(OO)接口。在这种情况下,我们使用 axes.Axes 为了在 figure.Figure .

第二种是基于Matlab,使用基于状态的接口。它被封装在 pyplot 模块。见 pyplot tutorials 要更深入地了解Pyplot接口。

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

  • 图形是可能包含1个或多个轴的最终图像。
  • 轴代表一个单独的绘图(不要将其与“轴”一词混淆,该词指绘图的X/Y轴)。

我们称之为直接从轴进行绘图的方法,这使我们在自定义绘图时更加灵活和强大。

注解

通常,尝试在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)

入门

这些数据自然地被可视化为条形图,每组一个条形图。为了使用面向对象的方法实现这一点,我们首先生成 figure.Figureaxes.Axes . 这个图形就像一张画布,坐标轴是画布的一部分,我们将在画布上进行特殊的可视化。

注解

图形上可以有多个轴。有关如何执行此操作的信息,请参见 Tight Layout tutorial .

fig, ax = plt.subplots()
lifecycle

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

lifecycle

出:

<BarContainer object of 10 artists>

控制样式

Matplotlib中有许多样式可供选择,以便根据需要定制可视化效果。要查看样式列表,我们可以使用 style .

出:

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

现在,让我们重新绘制上面的图,看看它是什么样子的:

lifecycle

出:

<BarContainer object of 10 artists>

样式控制许多内容,如颜色、线条宽度、背景等。

自定义绘图

现在我们有了一个我们想要的总体外观的情节,所以让我们对它进行微调,以便它可以打印。首先,让我们旋转X轴上的标签,使它们显示得更清楚。我们可以通过 axes.Axes.get_xticklabels() 方法:

lifecycle

如果我们想同时设置多个项目的属性,使用 pyplot.setp() 功能。这将获取matplotlib对象的列表(或多个列表),并尝试为每个对象设置一些样式元素。

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
lifecycle

出:

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

看起来这把底部的一些标签剪掉了。我们可以告诉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')
lifecycle

出:

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

接下来,我们将标签添加到绘图中。要使用OO接口实现这一点,我们可以使用 Artist.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')
Company Revenue

出:

[(-10000.0, 140000.0), Text(0.5, 44.08838834764833, 'Total Revenue'), Text(43.999999999999986, 0.5, 'Company'), Text(0.5, 1.0, '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')
Company Revenue

出:

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

对于标签,我们可以以函数的形式指定自定义格式准则。下面我们定义一个函数,它以整数作为输入,并返回字符串作为输出。与一起使用时 Axis.set_major_formatterAxis.set_minor_formatter ,它们将自动创建并使用 ticker.FuncFormatter 班级。

对于此函数 x 参数是原始的记号标签 pos 是刻度位置。我们只使用 x 但这两个论点都是必要的。

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

然后我们可以将这个函数应用于绘图上的标签。为此,我们使用 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)
Company Revenue

组合多个可视化效果

可以在同一个实例上绘制多个绘图元素 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 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(currency)
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
fig.subplots_adjust(right=.1)

plt.show()
Company Revenue

拯救我们的阴谋

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

出:

{'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" 使图形的边界适合我们的绘图。
# Uncomment this line to save the figure.
# fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")

脚本的总运行时间: (0分3.601秒)

关键词:matplotlib代码示例,codex,python plot,pyplot Gallery generated by Sphinx-Gallery