图表可视化#

备注

下面的示例假定您正在使用 Jupyter

本节演示通过图表进行可视化。有关表格数据可视化的信息,请参阅 Table Visualization 部分。

我们使用标准的约定来引用 matplotlib API:

We provide the basics in pandas to easily create decent looking plots. See the ecosystem page for visualization libraries that go beyond the basics documented here.

备注

所有对 np.random 的调用都使用 123456 作为种子。

基本绘图:plot#

我们将演示基础知识,有关一些高级策略,请参阅 cookbook

Series 和 DataFrame 上的 plot 方法只是 plt.plot() 的一个简单封装:

如果索引包含日期,它会调用 gcf().autofmt_xdate() 来尝试根据上方内容优化 x 轴的格式。

在 DataFrame 上,plot() 是一种方便的方法,可以绘制所有带标签的列:

您可以使用 plot() 中的 xy 关键字将一列与另一列进行绘图:

备注

有关更多格式设置和样式选项,请参阅下面的 formatting

其他绘图#

绘图方法除了默认的折线图外,还允许几种绘图样式。这些方法可以作为 kind 关键字参数提供给 plot() ,包括:

例如,条形图可以按以下方式创建:

您也可以使用 DataFrame.plot.<kind> 方法创建这些其他图,而不是提供 kind 关键字参数。这样可以更轻松地发现绘图方法及其使用的具体参数:

除了这些 kind 类型之外,还有 DataFrame.hist()DataFrame.boxplot() 方法,它们使用单独的接口。

最后,pandas.plotting 中有几个 plotting functions ,它们接受 SeriesDataFrame 作为参数。这些包括:

图表还可以附带 errorbarstables

条形图#

对于带标签的非时间序列数据,您可能希望生成条形图:

调用 DataFrame 的 plot.bar() 方法会生成一个多条形图:

要生成堆叠条形图,请传递 stacked=True

要获得水平条形图,请使用 barh 方法:

直方图#

可以通过调用 DataFrame.plot.hist()Series.plot.hist() 方法来绘制直方图。

可以使用 stacked=True 来堆叠直方图。可以使用 bins 关键字更改 bin 大小。

您可以传递 matplotlib hist 支持的其他关键字。例如,可以通过 orientation='horizontal'cumulative=True 来绘制水平和累积直方图。

有关更多信息,请参阅 hist 方法和 matplotlib hist documentation

用于绘制直方图的现有接口 DataFrame.hist 仍然可以使用。

DataFrame.hist() 在多个子图上绘制列的直方图:

可以指定 by 关键字来绘制分组直方图:

此外,也可以在 DataFrame.plot.hist() 中指定 by 关键字。

在 1.4.0 版本发生变更.

箱线图#

可以通过调用 Series.plot.box()DataFrame.plot.box() ,或者 DataFrame.boxplot() 来绘制箱线图,以可视化每列中值的分布。

例如,这是一个包含10个[0,1)区间上的均匀随机变量观测值的五次试验的箱线图。

可以通过传递 color 关键字来为箱线图着色。你可以传递一个 dict,其键为 boxeswhiskersmedianscaps。如果 dict 中缺少某些键,则为相应的艺术家使用默认颜色。此外,boxplot 还有 sym 关键字来指定异常值样式。

当通过 color 关键字传递其他类型的参数时,它将直接传递给 matplotlib,用于所有 boxeswhiskersmedianscaps 的着色。

颜色将应用于要绘制的每个箱体。如果你想要更复杂的着色,可以通过传递 return_type 来获取每个绘制的艺术家。

此外,你还可以传递 matplotlib boxplot 支持的其他关键字。例如,可以通过 vert=Falsepositions 关键字绘制水平和自定义位置的箱线图。

更多信息请参阅 boxplot 方法和 matplotlib boxplot documentation

现有的 DataFrame.boxplot 接口仍然可以用来绘制箱线图。

你可以使用 by 关键字参数来创建分层箱线图,从而生成分组。例如,

你也可以传递列的子集进行绘图,以及按多个列进行分组:

你也可以使用 DataFrame.plot.box() 创建分组,例如:

在 1.4.0 版本发生变更.

boxplot 中,可以使用 return_type 关键字来控制返回类型。有效选项为 {"axes", "dict", "both", None}。通过 DataFrame.boxplot 使用 by 关键字创建的分面也会影响输出类型:

return_type

分面

输出类型

None

axes

None

2-D ndarray of axes

'axes'

axes

'axes'

Series of axes

'dict'

dict of artists

'dict'

Series of dicts of artists

'both'

namedtuple

'both'

Series of namedtuples

Groupby.boxplot 始终返回一个 return_typeSeries

上面的子图首先按数值列拆分,然后按 g 列的值拆分。子图下方先按 g 列的值拆分,然后按数值列拆分。

面积图#

你可以使用 Series.plot.area()DataFrame.plot.area() 创建面积图。面积图默认是堆叠的。要生成堆叠面积图,每列的值必须全是正数或全是负数。

当输入数据包含 NaN 时,它将被自动填充为0。如果你想删除或用不同的值填充,请在调用 plot 之前使用 dataframe.dropna()dataframe.fillna()

要生成非堆叠图,请传递 stacked=False。透明度值默认为0.5,除非另有说明:

散点图#

可以使用 DataFrame.plot.scatter() 方法绘制散点图。散点图需要数值列作为 x 轴和 y 轴。这些可以通过 xy 关键字指定。

要在单个坐标轴上绘制多个列组,请重复调用 plot 方法并指定目标 ax。建议使用 colorlabel 关键字来区分每个组。

关键字 c 可以是列名,用于为每个点提供颜色:

如果将分类列传递给 c,则会生成离散的颜色条:

在 1.3.0 版本加入.

你可以传递 matplotlib scatter 支持的其他关键字。下面的示例显示了一个使用 DataFrame 中的列作为气泡大小的气泡图。

更多信息请参阅 scatter 方法和 matplotlib scatter documentation

六边形分块图#

你可以使用 DataFrame.plot.hexbin() 创建六边形分块图。当数据过于密集,无法单独绘制每个点时,六边形分块图可能是一种有用的散点图替代方案。

一个有用的关键字参数是 gridsize;它控制 x 方向上的六边形数量,默认为 100。较大的 gridsize 意味着有更多、更小的分块。

默认情况下,将计算每个 (x, y) 点周围计数的直方图。你可以通过将值传递给 Creduce_C_function 参数来指定替代聚合方法。 C 指定每个 (x, y) 点的值,而 reduce_C_function 是一个接受一个参数的函数,它将一个分块中的所有值减少为单个数字(例如 meanmaxsumstd)。在此示例中,位置由列 ab 指定,而值由列 z 指定。分块使用 NumPy 的 max 函数进行聚合。

更多信息请参阅 hexbin 方法和 matplotlib hexbin documentation

饼图#

您可以使用 DataFrame.plot.pie()Series.plot.pie() 创建饼图。如果您的数据包含任何 NaN,它们将自动填充为 0。如果您的数据中存在任何负值,将引发 ValueError

对于饼图,最好使用方形图,即图形的宽高比为 1。您可以创建宽度和高度相等的图形,或者在绘图后通过调用返回的 axes 对象的 ax.set_aspect('equal') 来强制将宽高比设置为相等。

请注意,使用 DataFrame 创建饼图需要您通过 y 参数指定目标列,或者设置 subplots=True。当指定 y 时,将绘制选定列的饼图。如果指定了 subplots=True,则将每个列的饼图绘制为子图。默认情况下,每个饼图都会绘制一个图例;指定 legend=False 可以隐藏它。

您可以使用 labelscolors 关键字参数来指定每个扇形的标签和颜色。

警告

大多数 pandas 绘图都使用 labelcolor 参数(注意这些参数后面没有“s”)。为了与 matplotlib.pyplot.pie() 保持一致,您必须使用 labelscolors

如果您想隐藏扇形标签,请指定 labels=None。如果指定了 fontsize,该值将应用于扇形标签。此外,还可以使用 matplotlib.pyplot.pie() 支持的其他关键字参数。

如果您传入的总和小于 1.0 的值,它们将被重新缩放,使其总和为 1。

更多信息请参阅 matplotlib pie documentation

带有缺失数据的绘图#

pandas 在处理包含缺失数据的 DataFrames``Series` 时会尝试采取务实的方式。缺失值会被丢弃、忽略或填充,具体取决于绘图类型。

绘图类型

NaN 处理

线图

在 NaN 处留空

线图(堆叠)

填充 0

条形图

填充 0

散点图

丢弃 NaNs

直方图

逐列丢弃 NaNs

箱型图

逐列丢弃 NaNs

面积图

填充 0

KDE 图

逐列丢弃 NaNs

六边形图

丢弃 NaNs

饼图

填充 0

如果这些默认设置中的任何一个不是您想要的,或者您想明确如何处理缺失值,请考虑在绘图前使用 fillna()dropna()

绘图工具#

这些函数可以从 pandas.plotting 导入,并接受 SeriesDataFrame 作为参数。

散点图矩阵#

您可以使用 pandas.plotting 中的 scatter_matrix 方法创建散点图矩阵:

密度图#

您可以使用 Series.plot.kde()DataFrame.plot.kde() 方法创建密度图。

安德鲁斯曲线#

安德鲁斯曲线允许人们将多维数据绘制成大量的曲线,这些曲线通过样本的属性作为傅立叶级数的系数来创建,更多信息请参阅 Wikipedia entry 。通过为每个类着色不同的曲线,可以可视化数据聚类。属于同一类的样本的曲线通常会更接近并形成更大的结构。

注意:“鸢尾花”数据集可在此 here 获取。

平行坐标图#

平行坐标图是一种绘制多维数据的绘图技术,有关介绍,请参阅 Wikipedia entry 。平行坐标图允许人们直观地看到数据中的聚类并估算其他统计量。在平行坐标图中,点被表示为连接的线段。每条垂直线代表一个属性。一组连接的线段代表一个数据点。趋于聚类的点将显得更近。

滞后图#

滞后图用于检查数据集或时间序列是否随机。随机数据在滞后图中不应显示任何结构。非随机结构意味着底层数据不是随机的。可以传递 lag 参数,当 lag=1 时,绘图本质上是 data[:-1]data[1:] 的关系图。

自相关图(Autocorrelation plot)#

自相关图常用于检验时间序列的随机性。这是通过计算数据在不同时间延迟下的自相关性来实现的。如果时间序列是随机的,那么对于任何时间延迟,其自相关性都应接近于零。如果时间序列是非随机的,则一个或多个自相关性将显著非零。图中显示的水平线对应于 95% 和 99% 的置信区间。虚线是 99% 的置信区间。有关自相关图的更多信息,请参见 Wikipedia entry

Bootstrap 图(Bootstrap plot)#

Bootstrap 图用于直观评估统计量(如均值、中位数、极差等)的不确定性。从数据集中选择一个指定大小的随机子集,计算该子集的统计量,然后重复此过程指定的次数。由此产生的图和直方图构成了 Bootstrap 图。

RadViz#

RadViz 是一种可视化多变量数据的方法。它基于一个简单的弹簧张力最小化算法。基本原理是你在平面上设置一组点。在我们的例子中,它们在单位圆上等距分布。每个点代表一个单独的属性。然后,你假定数据集中每个样本都通过一个弹簧连接到这些点中的每一个,弹簧的刚度与该属性的数值成正比(它们被归一化到单位区间)。我们的样本在该平面上达到平衡(作用在样本上的力处于平衡状态)的点就是绘制样本点的相应位置。根据样本所属的类别,它会被赋予不同的颜色。有关 RadViz 的更多信息,请参见 R 包 Radviz

注意:“鸢尾花”数据集可在此 here 获取。

图表格式化#

设置图表样式#

从 1.5 版本开始,matplotlib 提供了一系列预配置的绘图样式。设置样式可以轻松地为图表提供所需的通用外观。设置样式非常简单,只需在创建图表之前调用 matplotlib.style.use(my_plot_style)。例如,你可以编写 matplotlib.style.use('ggplot') 来获得 ggplot 风格的图表。

你可以在 matplotlib.style.available 中查看各种可用的样式名称,并且可以很容易地尝试它们。

通用图表样式参数#

大多数绘图方法都有一组关键字参数,用于控制生成图表的布局和格式:

对于每种类型的图表(例如 linebarscatter),任何额外的参数关键字都会被传递给相应的 matplotlib 函数(ax.plot()ax.bar()ax.scatter() )。这些参数可用于控制 pandas 提供的样式之外的其他附加样式。

控制图例#

你可以将 legend 参数设置为 False 来隐藏默认显示的图例。

控制标签#

你可以设置 xlabelylabel 参数为图表提供自定义的 x 轴和 y 轴标签。默认情况下,pandas 会将索引名称作为 xlabel,而 ylabel 则留空。

刻度#

你可以传递 logy 参数来获得对数刻度的 Y 轴。

还可以参考 logxloglog 关键字参数。

在次 Y 轴上绘图#

要在次 Y 轴上绘图,请使用 secondary_y 关键字:

要绘制 DataFrame 中的某些列,请将列名传递给 secondary_y 关键字:

请注意,在次 Y 轴上绘制的列在图例中会自动标记为“(right)”。要关闭自动标记,请使用 mark_right=False 关键字:

时间序列图的自定义格式化程序#

pandas 为时间序列图提供了自定义格式化程序。这些格式化程序会更改日期和时间轴标签的格式。默认情况下,自定义格式化程序仅应用于 pandas 使用 DataFrame.plot()Series.plot() 创建的图表。要让它们应用于所有图表(包括 matplotlib 创建的图表),请设置选项 pd.options.plotting.matplotlib.register_converters = True 或使用 pandas.plotting.register_matplotlib_converters()

抑制刻度分辨率调整#

对于规则频率的时间序列数据,pandas 会自动调整刻度分辨率。在 pandas 无法推断频率信息的有限情况下(例如,在外部创建的 twinx 中),您可以选择抑制此行为以实现对齐。

这是默认行为,请注意 x 轴刻度标签是如何执行的:

使用 x_compat 参数,您可以抑制此行为:

如果您需要抑制多个绘图,可以在 with 语句中使用 pandas.plotting.plot_params 中的 use 方法:

自动日期刻度调整#

TimedeltaIndex 现在使用原生的 matplotlib 刻度定位器方法,对于刻度标签重叠的图形,调用 matplotlib 的自动日期刻度调整很有用。

更多信息请参阅 autofmt_xdate 方法和 matplotlib documentation

子图#

DataFrame 中的每个 Series 都可以使用 subplots 关键字绘制在不同的轴上:

使用布局和定位多个轴#

子图的布局可以通过 layout 关键字指定。它可以接受 (行数, 列数)layout 关键字也可以在 histboxplot 中使用。如果输入无效,将引发 ValueError

layout 指定的行数 x 列数所包含的轴的数量必须大于所需的子图数量。如果布局可以包含比所需更多的轴,则不会绘制空白轴。与 NumPy 数组的 reshape 方法类似,您可以为其中一个维度使用 -1,以便在给定另一个维度的情况下自动计算所需的行数或列数。

上面的例子与使用以下方法是相同的:

所需的列数(3)是从要绘制的 Series 的数量和给定的行数(2)推断出来的。

您可以通过 ax 关键字将预先创建的多个轴作为列表传递。这允许更复杂的布局。传递的轴必须与要绘制的子图数量相同。

当通过 ax 关键字传递多个轴时,layoutsharexsharey 关键字不会影响输出。您应该显式地传递 sharex=Falsesharey=False,否则您会看到一个警告。

另一个选项是将 ax 参数传递给 Series.plot() 以在特定轴上绘图:

带误差条绘图#

DataFrame.plot()Series.plot() 支持带误差条的绘图。

水平和垂直误差条可以作为参数传递给 plot()xerryerr 关键字参数。误差值可以使用多种格式指定:

  • 作为误差的 DataFramedict,其列名与绘图 DataFramecolumns 属性匹配,或者与 Seriesname 属性匹配。

  • 作为 str,指示绘图 DataFrame 的哪个列包含误差值。

  • 作为原始值(listtuplenp.ndarray)。必须与绘图 DataFrame Series 的长度相同。

以下是如何从原始数据轻松绘制组均值及其标准差的一种方法。

也支持不对称误差条,但此时必须提供原始误差值。对于长度为 NSeries ,应提供一个 2xN 的数组,表示下限和上限(或左侧和右侧)误差。对于 MxNDataFrame ,不对称误差应在一个 Mx2xN 的数组中。

以下是如何使用不对称误差条绘制最小/最大范围的一种方法。

绘制表格#

使用 matplotlib 表格绘图现在通过 table 关键字在 DataFrame.plot()Series.plot() 中得到支持。 table 关键字可以接受 boolDataFrameSeries 。绘制表格的简单方法是指定 table=True。数据将被转置以满足 matplotlib 的默认布局。

此外,您也可以将另一个 DataFrameSeries 传递给 table 关键字。数据将按打印方法显示的方式绘制(不自动转置)。如果需要,应手动转置,如下面的示例所示。

还有一个辅助函数 pandas.plotting.table,它从 DataFrameSeries 创建一个表格,并将其添加到 matplotlib.Axes 实例中。此函数可以接受 matplotlib 的 table 函数接受的关键字参数。

注意: 你可以通过 axes.tables 属性在 axes 上获取表格实例,以便进行进一步的修饰。更多信息请参阅 matplotlib table documentation

颜色映射#

当绘制大量列时,一个潜在的问题是由于默认颜色的重复而难以区分某些序列。为了解决这个问题,DataFrame 绘图支持使用 colormap 参数,该参数接受 Matplotlib 的 colormap 或一个已在 Matplotlib 中注册的颜色映射名称字符串。默认 matplotlib 颜色映射的可视化效果可在此 here 查看。

由于 matplotlib 不直接支持线形图的颜色映射,颜色是根据 DataFrame 中列数的均匀间隔来选择的。不考虑背景颜色,因此某些颜色映射会产生不易看到的线条。

要使用 cubehelix 颜色映射,我们可以传递 colormap='cubehelix'

或者,我们可以传递颜色映射本身:

颜色映射也可以用于其他类型的图,例如条形图:

平行坐标图:

安德鲁斯曲线图:

直接使用 Matplotlib 绘图#

在某些情况下,直接使用 matplotlib 准备绘图仍然是可取或必要的,例如当 pandas 尚未(或不支持)某种类型的绘图或自定义时。SeriesDataFrame 对象表现得像数组,因此可以直接传递给 matplotlib 函数,而无需显式转换。

pandas 还自动注册了可识别日期索引的格式化器和定位器,从而将日期和时间支持扩展到 matplotlib 几乎所有可用的绘图类型。尽管这种格式化不像通过 pandas 绘图那样提供相同的精细度,但在绘制大量点时可能更快。

绘图后端#

pandas 可以通过第三方绘图后端进行扩展。主要思想是允许用户选择一个不同于基于 Matplotlib 的默认后端的绘图后端。

这可以通过在 plot 函数中将 'backend.module' 作为 backend 参数来完成。例如:

>>> Series([1, 2, 3]).plot(backend="backend.module")

或者,你也可以全局设置此选项,这样就不需要在每次 plot 调用中指定关键字。例如:

>>> pd.set_option("plotting.backend", "backend.module")
>>> pd.Series([1, 2, 3]).plot()

或者:

>>> pd.options.plotting.backend = "backend.module"
>>> pd.Series([1, 2, 3]).plot()

这大致相当于:

>>> import backend.module
>>> backend.module.plot(pd.Series([1, 2, 3]))

然后后端模块可以使用其他可视化工具(Bokeh、Altair、hvplot 等)来生成绘图。在 the ecosystem page 上列出了一些实现了 pandas 后端的库。

开发者指南可在 https://pandas.pydata.org/docs/dev/development/extending.html#plotting-backends 找到