Skip to content

绘图与可视化

简明matplotlib API入门

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from io import BytesIO

执行plt.show()时报错: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.

执行下面命令,得到pltbackend是用agg

plt.get_backend()

例如:下面两种表达方式效果一样。

ax.plot(x, y, 'g--')
ax.plot(x, y, linestyle='--', color='g')
Out[6]: 'agg'

安装下面几个包:

sudo zypper in python-tk python3-tk
sudo zypper in plplot-tcltk-devel plplot-tcltk-libs
pip install tk

添加下面到python代码中。

import matplotlib.pyplot as plt
mpl.use('TkAgg')

执行后报下面错误: your Python may not be configured for Tk

进入python源码目录,重新编译例如:下面两种表达方式效果一样。

ax.plot(x, y, 'g--')
ax.plot(x, y, linestyle='--', color='g')
james@lizard:/opt/Python-3.9.6> sudo make
james@lizard:/opt/Python-3.9.6> sudo make install

问题解决,即使不加入mpl.use('TkAgg'),执行plt.show()也是可以输出图像。

图片与子图

matplotlib所绘制的图位于图片(Figure)对象中。可以使用plt.figure生成一个新的图片。 使用add_subplot创建一个或多个子图(subplot)。

pltax绘图。

fig = plt.figure()
# plt: 先生成了一个画布,然后在这个画布上隐式的生成一个画图区域来进行画图
# plt.plot([1, 2, 3, 4])
# plt.show()
# ax: 先生成一个画布(2×2的区域,最多放四个图形),然后在此画布上,选定一个子区域画了一个子图(序号1代表第一个区域)
ax1 = fig.add_subplot(2, 2, 1)  # 也可以写成fig.add_subplot(221)
ax1.plot([1, 2, 3, 4], [1, 4, 3, 2])  # 输出图片到第一个区域。
# 第一个参数是数据集里各个数据点的X值的集合
# 第二个参数数据集里各个数据点的Y值的集合。
# 不是数学上常见的成对坐标点如(x1,y1)、(x2,y2)、...、(xn,yn)的格式,而是 (x1,x2,...,xn)和(y1,y2,...,yn) 。
plt.show()

看下面例子,增加子图后的数据可视化效果。

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
ax1.plot(np.random.randn(50).cumsum(), 'k--')  # 在第三个区域输出图像。'k--’是用于绘制黑色分段线的style选项。
ax2.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
ax3.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))
plt.show()

plt.subplots 通过matplotlibsubplots方法,使用子图网格创建图片,然后返回包含了已生成子图对象的NumPy数组。 数组axes可以像二维数组那样方便地进行索引,例如,axes[0, 1]

plt.subplots参数选项:

  • nrows:可选的,整型,默认为1。子图网格的行数。
  • ncols:可选的,整型,默认为1。子图网格的列数。
  • sharex:可选的,默认为False。可选值如下:
  • True或all,所有子图共享x轴
  • False或none,每个子图的x轴都是独立的
  • row,每行子图共享一个x轴
  • col,每列子图共享一个x轴
  • sharey:类似于sharex,设置y轴的共享方式。当某列共享一个x轴时,只有底部的子图会创建x轴标记。同样的,如果某行共享一个y轴时,只有行的第一列子图会创建y轴标记。
  • squeeze :可选的,布尔型,默认为True。是否压缩返回的Axes数组。如果为True,当只有一个子图,即nrows和ncols均为1时,返回一个单独的Axes对象,当有N*1和1*M个子图时,返回一个一维Axes对象数组。当有N*M个子图(N>1,M>1)时,返回二维数组。如果为False,则总是返回二维数组。
  • num:可选的,整型或字符串,默认为None。是matplotlib.pyplot.figure的关键字,用于设置图像数字或标签。如果未设置此参数,会创建一个新的图像,并递增图像编号,figure对象会将编号保存在number属性中。如果设置了此参数,并且存在参数指定的图像,则会返回此图像的引用,如果不存在则会创建新的图像并返回它的引用。如果是字符串,则窗口标题会被设置为此字符串的值。
  • subplot_kw:可选的,字典类型。包含传递给用于创建子图的调用add_subplot的关键字参数。
  • gridspec_kw:可选的,字典类型。包含传递给用于创建子图网格的GridSpec构造函数的关键字参数。
fig, axes = plt.subplots(2, 3)
print(axes)  # 将生成的axes对象放入NumPy数组。
# [[<AxesSubplot:> <AxesSubplot:> <AxesSubplot:>]
#  [<AxesSubplot:> <AxesSubplot:> <AxesSubplot:>]]

调整子图周围的间距。 默认情况下,matplotlib会在子图的外部和子图之间留出一定的间距。 这个间距都是相对于图的高度和宽度来指定的,手动调整图的大小,那么间距会自动调整。 也可以使用图对象上的subplots_adjust方法更改间距,也可以用作顶层函数。

fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)

for i in range(2):
    for j in range(2):
        axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5)

plt.subplots_adjust(wspace=0, hspace=0)
plt.show()

上面输出图像的轴标签是存在重叠的。matplotlib并不检查标签是否重叠,因此在类似情况下你需要通过显式指定刻度位置和刻度标签的方法来修复轴标签。

颜色、标记和线类型

matplotlib的主函数plot接收带有xy轴的数组以及一些可选的字符串缩写参数来指明颜色和线类型。 例如:下面两种表达方式效果一样。

  • ax.plot(x, y, 'g--')
  • ax.plot(x, y, linestyle='--', color='g')
data = np.random.randn(30).cumsum()
plt.plot(data, 'ko--')
plt.show()
# 上面的代码可以写得更为显式:
plt.plot(data, color='k', linestyle='dashed', marker='o')
plt.show()
plt.plot(data, color='k', linestyle='dashed', marker='o', label='Default')
plt.show()
plt.plot(data, color='k', linestyle='dashed', marker='o', label='steps-post', drawstyle='steps-post')
plt.show()

刻度、标签和图例

对于大多数图表修饰工作,有两种主要的方式:使用程序性的pyplot接口(即matplotlib.pyplot)和更多面向对象的原生matplotlib API。

pyplot接口设计为交互式使用,包含了像xlimxticksxticklabels等方法。这些方法分别控制了绘图范围、刻度位置以及刻度标签。

  • 在没有函数参数的情况下调用,返回当前的参数值(例如plt.xlim()返回当前的x轴绘图范围)。
  • 传入参数的情况下调用,并设置参数值(例如plt.xlim([0, 10])会将x轴的范围设置为0到10)。

所有的这些方法都会在当前活动的或最近创建的AxesSubplot上生效。 这些方法中的每一个对应于子图自身的两个方法。比如xlim对应于ax.get_limax.set_lim。 推荐使用subplot的实例方法,因为这样更为显式(尤其是在处理多个子图时)。

data = np.random.randn(1000).cumsum()
fig = plt.figure()

# 设定子图
ax = fig.add_subplot(1, 1, 1)

# 设定x轴对应参数:
# 设定x轴刻度
ax.set_xticks([0, 250, 500, 750, 1000])
# 设定x轴标签
ax.set_xticklabels(['one(0)', 'two(250)', 'three(500)', 'four(750)', 'five(1000)'], rotation=30, fontsize='small')
# 给x轴一个名称
ax.set_xlabel('Stages')

# 设定y轴对应参数:
# 未指定的参数由系统默认产生。
ax.set_ylabel('Steps')

# 给子图添加一个标题
ax.set_title('My first matplotlib plot')

# 给子图添加一个图例(如:给子图内一个图形曲线添加一个label)
ax.plot(data, 'k--', label='Label One')

# loc参数告诉matplotlib在哪里放置图表。legend方法有多个其他的位置参数loc。
ax.legend(loc='best')  # 或者plt.legend(loc='best') 。

# 在图形坐标为(0, 0)的位置添加一个lable
ax.text(0, 0, 'Hello World1', family='monospace', fontsize=10)

# 给子图添加annotate。用一个箭头指向要注释的地方,再写上一段话的行为,叫做annotate。
# * s: 注释的内容,一段文字;
# * xytext: 这段文字所处的位置;
# * xy: 箭头指向的位置;
# * arrowprops: 通过arrowstyle表明箭头的风格或种类。
ax.annotate('Zero is here!', xytext=(20, 20), xy=(1, 1), arrowprops=dict(arrowstyle='->'))

# 给子图添加一些图形
# matplotlib含有表示多种常见图形的对象,这些对象的引用是patches。
# 一些图形,比如Rectangle(矩形)和Circle(圆形),可以在matplotlib.pyplot中找到,但图形的全集位于matplotlib.patches。
rect = plt.Rectangle((10, 5), 100, 15, color='k', alpha=0.3)
circ = plt.Circle((200, 9), 95, color='b', alpha=0.3)
pgon = plt.Polygon([[500, 5], [600, -5], [700, 30]], color='g', alpha=0.5)

ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)

# 将图片保存到文件
# 文件类型是从文件扩展名中推断出来的。所以如果你使用.pdf,则会得到一个PDF。
# 几个重要的选项:dpi,它控制每英寸点数的分辨率;bbox_inches,可以修剪实际图形的空白。
plt.savefig('../examples/figpath.png', dpi=400, bbox_inches='tight')

# saveifg并非一定是写到硬盘的,它可以将图片写入到所有的文件型对象中,例如BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plot_data = buffer.getvalue()

plt.show()

matplotlib设置

matplotlib配置了配色方案和默认设置,通过全局参数来定制,包括图形大小、子图间距、颜色、字体大小和网格样式等等。 使用rc方法是使用Python编程修改配置的一种方式。 rc的第一个参数是你想要自定义的组件,比如'figure'、'axes'、'xtick'、'ytick'、'grid'、'legend'等等。 之后,可以按照关键字参数的序列指定新参数。

字典是一种在程序中设置选项的简单方式。比如:

plt.rc('figure', figsize=(10, 10))
font_options = {
    'family': 'monospace', 
    'weight': 'bold', 
    'size': 'small'
}
plt.rc('font', **font_options)

使用pandas和seaborn绘图

pandas自身有很多内建方法可以简化从DataFrame和Series对象生成可视化的过程。 另一个库是seabornseaborn简化了很多常用可视化类型的生成。 导入seaborn会修改默认的matplotlib配色方案和绘图样式,这会提高图表的可读性和美观性。 即使不使用seaborn的API,也可以导入seaborn来为通用matplotlib图表提供更好的视觉美观度。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

折线图

Series和DataFrame都有一个plot属性,用于绘制基本的图形。默认情况下,plot()绘制的是折线图。

Series的plot参数:

  • ax: matplotlib子图对象axes,如果没有传值,则使用当前活动的子图默认使用gca()
  • alpha: 图片不透明度(0到1)
  • data: 数据序列Series
  • figsize: 图像尺寸,tuple(宽度,高度),注意这里的单位是英寸
  • fontsize: 设置刻度标签(xticks, yticks)的大小
  • grid: 网格线(默认是打开的)
  • kind: 图类型:折线图,柱形图,横向柱形图,直方图,箱线图,密度图,面积图,饼图
  • label: 列的别名,作用在图例上
  • legend: 图例
  • loglog: x,y轴都使用对数刻度
  • logx: x轴使用对数刻度
  • logy: y轴使用对数刻度
  • mark_right: 双 y 轴时,在图例中的列标签旁增加显示 (right) 标识
  • position: 柱形图的柱子的位置设置
  • rot: 改变刻度标签(xticks, yticks)的旋转度(0到360)
  • secondary_y: 双 y 轴,在右边的第二个 y 轴
  • style: 线的样式,比如'ko--'
  • table: 将数据以表格的形式展示出来
  • title: 标题
  • use_index: 是否使用索引作为x刻度标签
  • xerr: 带误差线的柱形图
  • xlim: 横轴坐标刻度的取值范围
  • xticks: x轴刻度标签
  • yerr: 带误差线的柱形图
  • ylim: 纵轴坐标刻度的取值范围
  • yticks: y轴刻度标签
  • **kwds: matplotlib plot方法的其他参数

DataFrame的plot参数:

  • x : 指数据框列的标签或位置参数
  • y : 指数据框列的标签或位置参数
  • kind :
  • 'line' : 折线图
  • 'bar' : 条形图
  • 'barh' : 横向条形图
  • 'hist' : 柱状图
  • 'box' : 箱线图
  • 'kde' : Kernel的密度估计图,主要对柱状图添加Kernel 概率密度线
  • 'density' : 'kde'
  • 'area' : area plot
  • 'pie' : 饼图
  • 'scatter' : 散点图 需要传入columns方向的索引
  • 'hexbin' : hexbin plot
  • ax : 子图(axes, 也可以理解成坐标轴) 要在其上进行绘制的matplotlib subplot对象。如果没有设置,则使用当前matplotlib subplot。其中,变量和函数通过改变figure和axes中的元素(例如:title,label,点和线等等)一起描述figure和axes,也就是在画布上绘图。
  • subplots : 判断图片中是否有子图
  • sharex : 如果有子图,子图共x轴刻度,标签
  • sharey : 如果有子图,子图共y轴刻度,标签
  • layout : 子图的行列布局
  • figsize : 图片尺寸大小
  • use_index : 默认用索引做x轴
  • title : 图片的标题用字符串
  • grid : 图片是否有网格
  • legend : 子图的图例,添加一个subplot图例(默认为True)
  • style : 对每列折线图设置线的类型
  • logx : 设置x轴刻度是否取对数
  • logy : 设置y轴刻度是否取对数
  • loglog : 同时设置x,y轴刻度是否取对数
  • xticks : 设置x轴刻度值,序列形式(比如列表)
  • yticks : 设置y轴刻度,序列形式(比如列表)
  • xlim : 设置坐标轴x的范围,列表或元组形式
  • ylim : 设置坐标轴y的范围,列表或元组形式
  • rot : 设置轴标签(轴刻度)的显示旋转度数
  • fontsize : 设置轴刻度的字体大小
  • colormap : 设置图的区域颜色
  • colorbar : 图片柱子
  • position : Specify relative alignments for bar plot layout. From 0 (left/bottom-end) to 1 (right/top-end). Default is 0.5 (center)
  • layout : 布局(rows, columns) for the layout of the plot
  • table : 如果为正,则选择DataFrame类型的数据并且转换匹配matplotlib的布局
  • yerr : 带误差线的柱形图
  • xerr : 带误差线的柱形图
  • stacked : 生成堆积柱状图
  • sort_columns : 以字母表顺序绘制各列,默认使用前列顺序
  • secondary_y : 设置第二个y轴(右y轴)
  • mark_right : When using a secondary_y axis, automatically mark the column labels with “(right)” in the legend
  • kwds : Options to pass to matplotlib plotting method

Series

data1 = np.random.randn(10).cumsum(0)
s1 = pd.Series(
    data1,
    index=np.arange(0, 100, 10),
)
print(s1)
fig, axes = plt.subplots(3, 1)  # 3个子图
s1.plot.bar(ax=axes[0], color='k', alpha=0.7)  # 条形图(子图0),color='k’(柱子的颜色设置为黑色),alpha=0.7(图像的填充色设置为部分透明)
s1.plot.barh(ax=axes[1], color='k', alpha=0.7)  # 横向条形图(子图1)
s1.value_counts().plot.pie(ax=axes[2])  # 通过value_counts()对Series值频率进行可视化
plt.show()

DataFrame

data2 = np.random.randn(10, 4).cumsum(0)
df1 = pd.DataFrame(
    data2,
    columns=pd.Index(['A', 'B', 'C', 'D'], name='Genus'),
    index=np.arange(0, 100, 10)
)
print(df1)
fig, axes = plt.subplots(2, 1)  # 2个子图
df1.plot.kde(ax=axes[0], alpha=0.7, grid='True', title='KDE Figure', sharex=True)
df1.plot.bar(ax=axes[1], grid='True', title='Line Figure', sharex=True, use_index=False, stacked=True)
# 因为共享x轴,所以在KDE子图中指定use_index=False看不出效果。
# DataFrame的列名称"Genus"被用作了图例标题
# stacked=True来生成堆积柱状图
plt.show()

实例:绘制一个堆积柱状图,用于展示每个派对在每天的数据点占比。

交叉表是一种常用的分类汇总表格,用于频数分布统计,主要价值在于描述了变量间关系的深刻含义。

虽然两个(或以上)变量可以是分类的或数量的,但是以都是分类的情形最为常见。 Pandas的crosstab()方法能够快速构建交叉表,并可以通过参数加以个性化的设置。其中,第一个参数将构成交叉表的行,第二个参数将构成交叉表的列。

tips = pd.read_csv('../examples/tips.csv')
print(tips)
#      total_bill   tip smoker   day    time  size
# 0         16.99  1.01     No   Sun  Dinner     2
# 1         10.34  1.66     No   Sun  Dinner     3
# 2         21.01  3.50     No   Sun  Dinner     3
# 3         23.68  3.31     No   Sun  Dinner     2
# 4         24.59  3.61     No   Sun  Dinner     4
# ..          ...   ...    ...   ...     ...   ...
# 239       29.03  5.92     No   Sat  Dinner     3
# 240       27.18  2.00    Yes   Sat  Dinner     2
# 241       22.67  2.00    Yes   Sat  Dinner     2
# 242       17.82  1.75     No   Sat  Dinner     2
# 243       18.78  3.00     No  Thur  Dinner     2
# [244 rows x 6 columns]

party_counts = pd.crosstab(tips['day'], tips['size'])  # 对原始数据的day和size进行聚合,并构建交叉表,day作为行,size作为列。
print(party_counts)
# size  1   2   3   4  5  6
# day
# Fri   1  16   1   1  0  0
# Sat   2  53  18  13  1  0
# Sun   0  39  15  18  3  1
# Thur  1  48   4   5  1  3

# 没有太多的1人和6人派对,舍弃这些数据
party_counts = party_counts.loc[:, 2:5]
print(party_counts)
# size   2   3   4  5
# day
# Fri   16   1   1  0
# Sat   53  18  13  1
# Sun   39  15  18  3
# Thur  48   4   5  1

# 标准化至和为1:沿0轴(行)对每列求和,每行各值除以和,以确保每一行的值和为1,然后进行绘图
party_pcts = party_counts.div(party_counts.sum(1), axis=0)
print(party_pcts)
# size         2         3         4         5
# day
# Fri   0.888889  0.055556  0.055556  0.000000
# Sat   0.623529  0.211765  0.152941  0.011765
# Sun   0.520000  0.200000  0.240000  0.040000
# Thur  0.827586  0.068966  0.086207  0.017241

party_counts.plot.bar()
plt.show()

可以看到本数据集中的派对数量在周末会增加。

实例:使用seaborn进行按星期日期计算小费百分比。

Seaborn要求数据的输入类型为pandas的Dataframe或Numpy数组。

tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip'])
print(tips)
#      total_bill   tip smoker   day    time  size   tip_pct
# 0         16.99  1.01     No   Sun  Dinner     2  0.063204
# 1         10.34  1.66     No   Sun  Dinner     3  0.191244
# 2         21.01  3.50     No   Sun  Dinner     3  0.199886
# 3         23.68  3.31     No   Sun  Dinner     2  0.162494
# 4         24.59  3.61     No   Sun  Dinner     4  0.172069
# ..          ...   ...    ...   ...     ...   ...       ...
# 239       29.03  5.92     No   Sat  Dinner     3  0.256166
# 240       27.18  2.00    Yes   Sat  Dinner     2  0.079428
# 241       22.67  2.00    Yes   Sat  Dinner     2  0.096759
# 242       17.82  1.75     No   Sat  Dinner     2  0.108899
# 243       18.78  3.00     No  Thur  Dinner     2  0.190114
# [244 rows x 7 columns]

# barplot: 将点估计和置信区间显示为矩形条。条形图表示具有每个矩形的高度的数值变量的集中趋势的估计,并且使用误差条提供围绕该估计的不确定性的一些指示
# 柱子的值是tip_pct的平均值
# 柱子上画出的黑线代表的是95%的置信区间(置信区间可以通过可选参数进行设置)
# hue选项,允许我们通过一个额外的分类值将数据分离
# 带参数hue='time'时,四个不同颜色的柱子,每个柱子上有置信区间的黑线,刻度0.00~0.30,步长0.05
# 不带参数hue='time'时,两个不同颜色的柱子,分别代表Dinner和Lunch,不是每个柱子上都有置信区间的黑线,刻度0.00~0.30,步长0.05
sns.barplot(x='tip_pct', y='day', data=tips, hue='time', orient='h')  # 根据星期日期和时间计算的小费百分比
# sns.barplot(x='tip_pct', y='day', data=tips, orient='h')
sns.set(style="darkgrid", palette="deep")  # style="whitegrid"
plt.show()

直方图和密度图

直方图是一种条形图,用于给出值频率的离散显示。数据点被分成离散的,均匀间隔的箱,并且绘制每个箱中数据点的数量。

tips['tip_pct'].plot.hist(bins=50)  # 小费百分比的直方图
plt.show()

密度图是一种与直方图相关的图表类型,它通过计算可能产生观测数据的连续概率分布估计而产生。 通常的做法是将这种分布近似为“内核”的混合,也就是像正态分布那样简单的分布。 因此,密度图也被称为内核密度估计图(KDE)。

tips['tip_pct'].plot.density() # 小费百分比密度图
plt.show()

绘制直方图和连续密度估计sns.displot()

sns.distplot(tips['tip_pct'], bins=100, color='k')
plt.show()
# FutureWarning: `distplot` is a deprecated function and will be removed in a future version.
# Please adapt your code to use either `displot` (a figure-level function with similar flexibility)
# or `histplot` (an axes-level function for histograms).

散点图或点图

点图或散点图可以用于检验两个一维数据序列之间的关系。

实例:从statsmodels项目中载入了macrodata数据集,并选择了一些变量,之后计算对数差。

macro = pd.read_csv('../examples/macrodata.csv')
print(macro.head(5))
#      year  quarter   realgdp  realcons  ...  unemp      pop  infl  realint
# 0  1959.0      1.0  2710.349    1707.4  ...    5.8  177.146  0.00     0.00
# 1  1959.0      2.0  2778.801    1733.7  ...    5.1  177.830  2.34     0.74
# 2  1959.0      3.0  2775.488    1751.8  ...    5.3  178.657  2.74     1.09
# 3  1959.0      4.0  2785.204    1753.7  ...    5.6  179.386  0.27     4.06
# 4  1960.0      1.0  2847.699    1770.5  ...    5.2  180.007  2.31     1.19
# [5 rows x 14 columns]

data = macro[['cpi', 'm1', 'tbilrate', 'unemp']]
print(data.head(5))
#      cpi     m1  tbilrate  unemp
# 0  28.98  139.7      2.82    5.8
# 1  29.15  141.7      3.08    5.1
# 2  29.35  140.5      3.82    5.3
# 3  29.37  140.0      4.33    5.6
# 4  29.54  139.6      3.50    5.2

trans_data = np.log(data).diff().dropna()
print(trans_data[-5:])
#           cpi        m1  tbilrate     unemp
# 198 -0.007904  0.045361 -0.396881  0.105361
# 199 -0.021979  0.066753 -2.277267  0.139762
# 200  0.002340  0.010286  0.606136  0.160343
# 201  0.008419  0.037461 -0.200671  0.127339
# 202  0.008894  0.012202 -0.405465  0.042560

seabornregplot方法绘制散点图,并拟合出一个条线性回归线。(seaborn文档)

sns.regplot('m1', 'unemp', data=trans_data)
plt.title('Changes in log %s versus log %s ' % ('m1', 'unemp'))
plt.show()

在探索性数据分析中,能够查看一组变量中的所有散点图是有帮助的,这被称为成对图或散点图矩阵。 Seaborn有一个方便的pairplot函数,它支持在对角线上放置每个变量的直方图或密度估计值。 plot_ksw参数能够将配置选项传递给非对角元素上的各个绘图调用。

sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2})
plt.show()

分面网格和分类数据

如果数据集有额外的分组维度怎么办?使用分面网格是利用多种分组变量对数据进行可视化的方式。 seaborn拥有一个有效的内建函数factorplot,它可以简化多种分面绘图。

sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1])
plt.show()
# UserWarning: The `factorplot` function has been renamed to `catplot`.
# The original name will be removed in a future release. Please update your code.
# Note that the default `kind` in `factorplot` (`'point'`) has changed `'strip'` in `catplot`.
sns.catplot(x='day', y='tip_pct', hue='time', col='smoker', kind='box', data=tips[tips.tip_pct < 0.5])
plt.show()

其他Python可视化工具

自2010年以来,很多开发工作都集中在创建web交互式图形上。 借助像BokehPlotly 这样的工具,在web浏览器中创建动态的、交互式图像的工作现在已经可以实现。 可视化是一个活跃的研究领域。