利用Python进行数据分析4-绘图与可视化

tech2022-08-03  163

信息可视化(也叫绘图)是数据分析中最重要的⼯作之⼀。

matplotlib API⼊⻔

import numpy as np import pandas as pd PREVIOUS_MAX_ROWS = pd.options.display.max_rows pd.options.display.max_rows = 20 np.random.seed(12345) import matplotlib.pyplot as plt import matplotlib plt.rc('figure', figsize=(10, 6)) np.set_printoptions(precision=4, suppress=True)

matplotlib的通常引⼊约定是:

#导入包 import matplotlib.pyplot as plt

在Jupyter中运⾏%matplotlib notebook(或在IPython中运⾏%matplotlib),就可以创建⼀个简单的图形。如果⼀切设置正确,会看到下图:

import numpy as np data = np.arange(10) data #绘制简单的线图 plt.plot(data)

虽然seaborn这样的库和pandas的内置绘图函数能够处理许多普通的绘图任务,但如果需要⾃定义⼀些⾼级功能的话就必须学习matplotlib API。

Figure和Subplot

matplotlib的图像都位于Figure对象中。你可以⽤plt.figure创建⼀个新的Figure:

fig = plt.figure()

如果⽤的是IPython,这时会弹出⼀个空窗⼝,但在Jupyter中,必须再输⼊更多命令才能看到。plt.figure有⼀些选项,特别是figsize,它⽤于确保当图⽚保存到磁盘时具有⼀定的⼤⼩和纵横⽐。 不能通过空Figure绘图。必须⽤add_subplot创建⼀个或多个subplot才⾏:

ax1 = fig.add_subplot(2, 2, 1)

这条代码的意思是:图像应该是2×2的(即最多4张图),且当前选中的是4个subplot中的第⼀个(编号从1开始)。如果再把后⾯两个subplot也创建出来,最终得到的图像如下图所示:

fig = plt.figure() ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) #同时执行则在最后图形上进行绘制 #plt.plot(np.random.randn(50).cumsum(), 'k--')

如果这时执⾏⼀条绘图命令(如plt.plot([1.5, 3.5, -2, 1.6])), matplotlib就会在最后⼀个⽤过的subplot(如果没有则创建⼀ 个)上进⾏绘制,隐藏创建figure和subplot的过程。因此,如果 我们执⾏下列命令,你就会得到如下图所示的结果:

fig = plt.figure() ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) #同时执行则在最后图形上进行绘制 plt.plot(np.random.randn(50).cumsum(), 'k--')

"k–"是⼀个线型选项,⽤于告诉matplotlib绘制⿊⾊虚线图。上⾯那些由fig.add_subplot所返回的对象是AxesSubplot对象,直接调⽤它们的实例⽅法就可以在其它空着的格⼦⾥⾯画图了,如下图所示:

fig = plt.figure() ax1 = fig.add_subplot(2, 2, 1) ax2 = fig.add_subplot(2, 2, 2) ax3 = fig.add_subplot(2, 2, 3) #同时执行则在最后图形上进行绘制 plt.plot(np.random.randn(50).cumsum(), 'k--') #继续绘制两次 _ = ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3) ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))

你可以在matplotlib的⽂档中找到各种图表类型。 创建包含subplot⽹格的figure是⼀个⾮常常⻅的任务,matplotlib有⼀个更为⽅便的⽅法plt.subplots,它可以创建⼀个新的Figure,并返回⼀个含有已创建的subplot对象的NumPy数组:

fig, axes = plt.subplots(2, 3) axes

这是⾮常实⽤的,因为可以轻松地对axes数组进⾏索引,就好像是⼀个⼆维数组⼀样,例如axes[0,1]。你还可以通过sharex和sharey指定subplot应该具有相同的X轴或Y轴。在⽐较相同范围的数据时,这也是⾮常实⽤的,否则,matplotlib会⾃动缩放各图表的界限。有关该⽅法的更多信息,请参⻅表1。 下表为表1:

参数说明nrowssubplot的行数ncolssubplot的列数sharex所有subplot应该使用相同的的X轴刻度(调节xlim将影响所有subplot)sharey所有subplot应该使用相同的y轴刻度(调节ylim将影响所有的subplot)subplot_kw用于创建个subplot的关键字字典**fig_kw创建figure时的其他关键字,如plt.subplots(2,2,figsize=(8,6))

调整subplot周围的间距

默认情况下,matplotlib会在subplot外围留下⼀定的边距,并在subplot之间留下⼀定的间距。间距跟图像的⾼度和宽度有关,因此,如果你调整了图像⼤⼩(不管是编程还是⼿⼯),间距也会⾃动调整。利⽤Figure的subplots_adjust⽅法可以轻⽽易举地修改间距,此外,它也是个顶级函数: PS:调试过程中发现书中源代码无法运行,在此处更改了。

plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)

wspace和hspace⽤于控制宽度和⾼度的百分⽐,可以⽤作subplot之间的间距。下⾯是⼀个简单的例⼦,其中我将间距收缩到了0(如下图所示):

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)

不难看出,其中的轴标签重叠了。matplotlib不会检查标签是否重叠,所以对于这种情况,你只能⾃⼰设定刻度位置和刻度标签。后续的博客会将会详细介绍该内容。

颜色、标记和线型

matplotlib的plot函数接受⼀组X和Y坐标,还可以接受⼀个表示颜⾊和线型的字符串缩写。例如,要根据x和y绘制绿⾊虚线,你可以执⾏如下代码:

ax.plot(x, y, 'g--')

这种在⼀个字符串中指定颜⾊和线型的⽅式⾮常⽅便。在实际中,如果你是⽤代码绘图,你可能不想通过处理字符串来获得想要的格式。通过下⾯这种更为明确的⽅式也能得到同样的效果:

ax.plot(x, y, linestyle='--', color='g')

常⽤的颜⾊可以使⽤颜⾊缩写,你也可以指定颜⾊码(例如,’#CECECE’)。你可以通过查看plot的⽂档字符串查看所有线型的合集(在IPython和Jupyter中使⽤plot?)。 线图可以使⽤标记强调数据点。因为matplotlib可以创建连续线图,在点之间进⾏插值,因此有时可能不太容易看出真实数据点的位置。标记也可以放到格式字符串中,但标记类型和线型必须放在颜⾊后⾯(⻅下图):

from numpy.random import randn plt.plot(randn(30).cumsum(), 'ko--')

还可以将其写成更为明确的形式:

plt.plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')

在线型图中,⾮实际数据点默认是按线性⽅式插值的。可以通过drawstyle选项修改(⻅下图):

data = np.random.randn(30).cumsum() plt.plot(data, 'k--', label='Default') plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post') plt.legend(loc='best')

你可能注意到运⾏上⾯代码时有输出<matplotlib.lines.Line2D at…>。matplotlib会返回引⽤了新添加的⼦组件的对象。⼤多数时候,你可以放⼼地忽略这些输出。这⾥,因为我们传递了label参数到plot,我们可以创建⼀个plot图例,指明每条使⽤plt.legend的线。 笔记:你必须调⽤plt.legend(或使⽤ax.legend,如果引⽤了轴的话)来创建图例,⽆论你绘图时是否传递label标签选项。

刻度、标签和图例

对于⼤多数的图表装饰项,其主要实现⽅式有⼆:使⽤过程型的pyplot接⼝(例如,matplotlib.pyplot)以及更为⾯向对象的原⽣ matplotlib API。 pyplot接⼝的设计⽬的就是交互式使⽤,含有诸如xlim、xticks和xticklabels之类的⽅法。它们分别控制图表的范围、刻度位置、刻度标签等。其使⽤⽅式有以下两种:

调⽤时不带参数,则返回当前的参数值(例如,plt.xlim()返回当前的X轴绘图范围)。调⽤时带参数,则设置参数值(例如,plt.xlim([0,10])会将X轴 的范围设置为0到10)。

所有这些⽅法都是对当前或最近创建的AxesSubplot起作⽤的。它们各⾃对应subplot对象上的两个⽅法,以xlim为例,就是ax.get_xlim和ax.set_xlim。我更喜欢使⽤subplot的实例⽅法(因为我喜欢明确的事情,⽽且在处理多个subplot时这样也更清楚⼀些)。当然你完全可以选择⾃⼰觉得⽅便的那个。

设置标题、轴标签、刻度以及刻度标签

为了说明⾃定义轴,我将创建⼀个简单的图像并绘制⼀段随机漫步(如下图所示):

fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(np.random.randn(1000).cumsum())

要改变x轴刻度,最简单的办法是使⽤set_xticks和set_xticklabels。前者告诉matplotlib要将刻度放在数据范围中的哪些位置,默认情况下,这些位置也就是刻度标签。但我们可以通过set_xticklabels将任何其他的值⽤作标签: rotation选项设定x刻度标签倾斜30度。最后,再⽤set_xlabel为x轴设置⼀个名称,并⽤set_title设置⼀个标题(⻅下图的结果):

fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ticks = ax.set_xticks([0, 250, 500, 750, 1000]) labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small') ax.set_title('My first matplotlib plot') ax.set_xlabel('Stages') ax.plot(np.random.randn(1000).cumsum())

Y轴的修改⽅式与此类似,只需将上述代码中的x替换为y即可。X轴的类有集合⽅法,可以批量设定绘图选项。前⾯的例⼦,也可以写为:

props = { 'title': 'My first matplotlib plot', 'xlabel': 'Stages' } ax.set(**props)

添加图例

图例是另⼀种⽤于标识图表元素的重要⼯具。添加图例的⽅式有多种。最简单的是在添加subplot的时候传⼊label参数:

from numpy.random import randn fig = plt.figure(); ax = fig.add_subplot(1, 1, 1) ax.plot(randn(1000).cumsum(), 'k', label='one') ax.plot(randn(1000).cumsum(), 'k--', label='two') ax.plot(randn(1000).cumsum(), 'k.', label='three') #自动创建图例 ax.legend(loc='best')

legend⽅法有⼏个其它的loc位置参数选项。请查看⽂档字符串 (使⽤ax.legend?)。 loc告诉matplotlib要将图例放在哪。如果你不是吹⽑求疵的话,"best"是不错的选择,因为它会选择最不碍事的位置。要从图例中去除⼀个或多个元素,不传⼊label或传⼊label='nolegend’即可。

注解以及在Subplot上绘图

除标准的绘图类型,你可能还希望绘制⼀些⼦集的注解,可能是⽂本、箭头或其他图形等。注解和⽂字可以通过text、arrow和annotate函数进⾏添加。text可以将⽂本绘制在图表的指定坐标(x,y),还可以加上⼀些⾃定义格式:

ax.text(x, y, 'Hello world!', family='monospace', fontsize=10)

注解中可以既含有⽂本也含有箭头。例如,我们根据最近的标准普尔500指数价格(来⾃Yahoo!Finance)绘制⼀张曲线图,并标出2008年到2009年⾦融危机期间的⼀些重要⽇期。你可以在Jupyter notebook的⼀个⼩窗中试验这段代码(下图是结果):

from datetime import datetime fig = plt.figure() ax = fig.add_subplot(1, 1, 1) data = pd.read_csv('examples/spx.csv', index_col=0, parse_dates=True) spx = data['SPX'] spx.plot(ax=ax, style='k-') crisis_data = [ (datetime(2007, 10, 11), 'Peak of bull market'), (datetime(2008, 3, 12), 'Bear Stearns Fails'), (datetime(2008, 9, 15), 'Lehman Bankruptcy') ] for date, label in crisis_data: ax.annotate(label, xy=(date, spx.asof(date) + 75), xytext=(date, spx.asof(date) + 225), arrowprops=dict(facecolor='black', headwidth=4, width=2, headlength=4), horizontalalignment='left', verticalalignment='top') # Zoom in on 2007-2010 ax.set_xlim(['1/1/2007', '1/1/2011']) ax.set_ylim([600, 1800]) ax.set_title('Important dates in the 2008-2009 financial crisis')

这张图中有⼏个重要的点要强调:ax.annotate⽅法可以在指定的x和y坐标轴绘制标签。我们使⽤set_xlim和set_ylim⼈⼯设定起始和结束边界,⽽不使⽤matplotlib的默认⽅法。最后,用ax.set_title添加图标标题。更多有关注解的示例,请访问matplotlib的在线示例库。 图形的绘制要麻烦⼀些。matplotlib有⼀些表示常⻅图形的对象。这些对象被称为块(patch)。其中有些(如Rectangle和Circle),可以在matplotlib.pyplot中找到,但完整集合位于matplotlib.patches。 要在图表中添加⼀个图形,你需要创建⼀个块对象shp,然后通过ax.add_patch(shp)将其添加到subplot中(如下图所示):

fig = plt.figure() ax = fig.add_subplot(1, 1, 1) rect = plt.Rectangle((0.2, 0.75), 0.4, 0.15, color='k', alpha=0.3) circ = plt.Circle((0.7, 0.2), 0.15, color='b', alpha=0.3) pgon = plt.Polygon([[0.15, 0.15], [0.35, 0.4], [0.2, 0.6]], color='g', alpha=0.5) ax.add_patch(rect) ax.add_patch(circ) ax.add_patch(pgon)

如果查看许多常⻅图表对象的具体实现代码,你就会发现它们其实就是由块patch组装⽽成的。

将图表保存到⽂件

利⽤plt.savefig可以将当前图表保存到⽂件。该⽅法相当于Figure对象的实例⽅法savefig。例如,要将图表保存为SVG⽂件,你只需输⼊:

plt.savefig('figpath.svg')

⽂件类型是通过⽂件扩展名推断出来的。因此,如果你使⽤的是.pdf,就会得到⼀个PDF⽂件。我在发布图⽚时最常⽤到两个重要的选项是dpi(控制“每英⼨点数”分辨率)和bbox_inches(可以剪除当前图表周围的空⽩部分)。要得到⼀张带有最⼩⽩边且分辨率为400DPI的PNG图⽚,你可以:

plt.savefig('figpath.png', dpi=400, bbox_inches='tight')

savefig并⾮⼀定要写⼊磁盘,也可以写⼊任何⽂件型的对象,比如BytesIO:

from io import BytesIO buffer = BytesIO() plt.savefig(buffer) plot_data = buffer.getvalue()

表2列出了savefig的其它选项。下表为表二:

参数说明fname含有文件路径的字符串或Python的文件型对象。图像格式由文件拓展名推断得出dpi图像分辨率(每英寸点数),默认为100facecolor、edgecolor图像背景颜色,默认为“w”(白色)format显示设置文件格式(“png”,“pdf”,“svg”,“ps”…)bbox_inches图表需要保存部分。若果设置为“tight”,则尝试剪除图表周围的空白部分

matplotlib配置

matplotlib⾃带⼀些配⾊⽅案,以及为⽣成出版质量的图⽚⽽设定的默认配置信息。幸运的是,⼏乎所有默认⾏为都能通过⼀组全局参数进⾏⾃定义,它们可以管理图像⼤⼩、subplot边距、配⾊⽅案、字体⼤⼩、⽹格类型等。⼀种Python编程⽅式配置系统⽅法是使⽤rc⽅法。例如,要将全局的图像默认⼤⼩设置为10×10,你可以执⾏:

plt.rc('figure', figsize=(10, 10))

rc的第⼀个参数是希望⾃定义的对象, 如’figure’、‘axes’、‘xtick’、‘ytick’、‘grid’、'legend’等。其后可以跟上⼀系列的关键字参数。⼀个简单的办法是将这些选项写成⼀个字典:

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

要了解全部的⾃定义选项,请查阅matplotlib的配置⽂件matplotlibrc(位于matplotlib/mpl-data⽬录中)。如果对该⽂件进⾏了⾃定义,并将其放在你⾃⼰的.matplotlibrc⽬录中,则每次使⽤matplotlib时就会加载该⽂件。之后,我们会看到,seaborn包有若⼲内置的绘图主题或类型,它们使⽤了matplotlib的内部配置。

使用pandas和seaborn绘图

matplotlib实际上是⼀种⽐较低级的⼯具。要绘制⼀张图表,你得组装⼀些基本组件就⾏:数据展示(即图表类型:线型图、柱状图、盒形图、散布图、等值线图等)、图例、标题、刻度标签以及其他注解型信息。 在pandas中,我们有多列数据,还有⾏和列标签。pandas⾃身就有内置的⽅法,⽤于简化从DataFrame和Series绘制图形。另⼀个库seaborn(https://seaborn.pydata.org/),由Michael Waskom创建的静态图形库。Seaborn简化了许多常⻅可视类型的创建。 提示:引⼊seaborn会修改matplotlib默认的颜⾊⽅案和绘图类型,以提⾼可读性和美观度。即使你不使⽤seaborn API,你可能也会引⼊seaborn,作为提⾼美观度和绘制常⻅matplotlib图形的简化⽅法。

线型图

Series和DataFrame都有⼀个⽤于⽣成各类图表的plot⽅法。默认情况下,它们所⽣成的是线型图(如下图所示):

s = pd.Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10)) s.plot()

该Series对象的索引会被传给matplotlib,并⽤以绘制X轴。可以通过use_index=False禁⽤该功能。X轴的刻度和界限可以通过xticks和xlim选项进⾏调节,Y轴就⽤yticks和ylim。plot参数的完 整列表请参⻅下表。我只会讲解其中⼏个,剩下的就留给读者 ⾃⼰去研究了。 Series.plot参数的完整列表如下

参数说明label用于图例的标签ax要在其上进行绘制的matplotlib subplot对象。如果没有设置,则使用当前matplotlib subplotstyle要传给matplotlib的风格字符串alpha图表的填充不透明度(0到1之间)kind可以是‘line’,‘bar’,‘bath’,‘kde’logy在y轴上使用对数标尺use_index将对象的索引用作刻度标签rot旋转刻度标签(0-360)xticks用作X轴刻度的值yticks用作Y轴刻度的值xlimX轴的界限ylimY轴的界限grid显示轴网格线(默认打开)

pandas的⼤部分绘图⽅法都有⼀个可选的ax参数,它可以是⼀个matplotlib的subplot对象。这使你能够在⽹格布局中更为灵活地处理subplot的位置。 DataFrame的plot⽅法会在⼀个subplot中为各列绘制⼀条线,并⾃动创建图例(如下图所示):

df = pd.DataFrame(np.random.randn(10, 4).cumsum(0), columns=['A', 'B', 'C', 'D'], index=np.arange(0, 100, 10)) df.plot()

plot属性包含⼀批不同绘图类型的⽅法。例如,df.plot()等价于df.plot.line()。后⾯会学习这些⽅法。 笔记:plot的其他关键字参数会被传给相应的matplotlib绘图函数,所以要更深⼊地⾃定义图表,就必须学习更多有关matplotlib API的知识。 DataFrame还有⼀些⽤于对列进⾏灵活处理的选项,例如,是要将所有列都绘制到⼀个subplot中还是创建各⾃的subplot。详细 信息请参⻅下表。 下表为专⽤于DataFrame的plot参数。

参数说明subplots将各个DataFrame列绘制到单独的subplot中sharex如果subplots=True,则共用同一个x轴,包括刻度和界限sharey如果subplots=True,则共用同一个y轴figsize表示图像大小的元组titile表示图像标题的字符串legend添加一个subplot图例sort_columns以字母顺序绘制各列,默认使用当前列顺序

柱状图

plot.bar()和plot.barh()分别绘制⽔平和垂直的柱状图。这时Series和DataFrame的索引将会被⽤作X(bar)或Y(barh)刻度(如下图所示):

fig, axes = plt.subplots(2, 1) data = pd.Series(np.random.rand(16), index=list('abcdefghijklmnop')) data.plot.bar(ax=axes[0], color='k', alpha=0.7) data.plot.barh(ax=axes[1], color='k', alpha=0.7)

color='k’和alpha=0.7设定了图形的颜⾊为⿊⾊,并使⽤部分的填充透明度。对于DataFrame,柱状图会将每⼀⾏的值分为⼀组,并排显示,如下图所示:

df.plot.bar()

注意,DataFrame各列的名称"Genus"被⽤作了图例的标题。设置stacked=True即可为DataFrame⽣成堆积柱状图,这样每⾏的值就会被堆积在⼀起(如下图所示):

df.plot.barh(stacked=True, alpha=0.5)

笔记:柱状图有⼀个⾮常不错的⽤法:利⽤value_counts图形化显示Series中各值的出现频率,⽐如s.value_counts().plot.bar()。

再以本书前⾯⽤过的那个有关⼩费的数据集为例,假设我们想要做⼀张堆积柱状图以展示每天各种聚会规模的数据点的百分⽐。我⽤read_csv将数据加载进来,然后根据⽇期和聚会规模创建⼀张交叉表:

tips = pd.read_csv('examples/tips.csv') party_counts = pd.crosstab(tips['day'], tips['size']) party_counts

# Not many 1- and 6-person parties party_counts = party_counts.loc[:, 2:5]

然后进⾏规格化,使得各⾏的和为1,并⽣成图表(如图下所示):

# Normalize to sum to 1 party_pcts = party_counts.div(party_counts.sum(1), axis=0) party_pcts

party_pcts.plot.bar()

于是,通过该数据集就可以看出,聚会规模在周末会变⼤。 对于在绘制⼀个图形之前,需要进⾏合计的数据,使⽤seaborn可以减少⼯作量。⽤seaborn来看每天的⼩费⽐例(下图是结果):

import seaborn as sns tips['tip_pct'] = tips['tip'] / (tips['total_bill'] - tips['tip']) tips.head()

sns.barplot(x='tip_pct', y='day', data=tips, orient='h')

seaborn的绘制函数使⽤data参数,它可能是pandas的DataFrame。其它的参数是关于列的名字。因为⼀天的每个值有多次观察,柱状图的值是tip_pct的平均值。绘制在柱状图上的⿊线代表95%置信区间(可以通过可选参数配置)。 seaborn.barplot有颜⾊选项,使我们能够通过⼀个额外的值设置(⻅下图):

sns.barplot(x='tip_pct', y='day', hue='time', data=tips, orient='h') sns.set(style="whitegrid")

注意,seaborn已经⾃动修改了图形的美观度:默认调⾊板,图形背景和⽹格线的颜⾊。你可以⽤seaborn.set在不同的图形外观之间切换:

sns.set(style="whitegrid")

直方图和密度图

直⽅图(histogram)是⼀种可以对值频率进⾏离散化显示的柱状图。数据点被拆分到离散的、间隔均匀的⾯元中,绘制的是各⾯元中数据点的数量。再以前⾯那个⼩费数据为例,通过在Series使⽤plot.hist⽅法,我们可以⽣成⼀张“⼩费占消费总额百分⽐”的直⽅图(如下图所示):

tips['tip_pct'].plot.hist(bins=50)

与此相关的⼀种图表类型是密度图,它是通过计算“可能会产⽣观测数据的连续概率分布的估计”⽽产⽣的。⼀般的过程是将该分布近似为⼀组核(即诸如正态分布之类的较为简单的分布)。因此,密度图也被称作KDE(Kernel Density Estimate,核密度估计)图。使⽤plot.kde和标准混合正态分布估计即可⽣成⼀张密度图(⻅下图):

tips['tip_pct'].plot.density()

seaborn的distplot⽅法绘制直⽅图和密度图更加简单,还可以同时画出直⽅图和连续密度估计图。作为例⼦,考虑⼀个双峰分布,由两个不同的标准正态分布组成(⻅下图):

comp1 = np.random.normal(0, 1, size=200) comp2 = np.random.normal(10, 2, size=200) values = pd.Series(np.concatenate([comp1, comp2])) sns.distplot(values, bins=100, color='k')

散布图或点图

点图或散布图是观察两个⼀维数据序列之间的关系的有效⼿段。在下⾯这个例⼦中,我加载了来⾃statsmodels项⽬的macrodata数据集,选择了⼏个变量,然后计算对数差:

macro = pd.read_csv('examples/macrodata.csv') data = macro[['cpi', 'm1', 'tbilrate', 'unemp']] trans_data = np.log(data).diff().dropna() trans_data[-5:]

然后可以使⽤seaborn的regplot⽅法,它可以做⼀个散布图,并加⼀条线性回归的线(⻅下图):

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

在探索式数据分析⼯作中,同时观察⼀组变量的散布图是很有意义的,这也被称为散布图矩阵(scatter plot matrix)。纯⼿⼯创建这样的图表很费⼯夫,所以seaborn提供了⼀个便捷的pairplot函数,它⽀持在对⻆线上放置每个变量的直⽅图或密度估计(⻅下图):

#散布图矩阵 sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2})

你可能注意到了plot_kws参数。它可以让我们传递配置选项到⾮对⻆线元素上的图形使⽤。对于更详细的配置选项,可以查阅seaborn.pairplot⽂档字符串。

分面网格(facet grid)和类型数据

要是数据集有额外的分组维度呢?有多个分类变量的数据可视化的⼀种⽅法是使⽤⼩⾯⽹格。seaborn有⼀个有⽤的内置函数factorplot,可以简化制作多种分⾯图(⻅下图):

#多种分面图 sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1])

除了在分⾯中⽤不同的颜⾊按时间分组,我们还可以通过给每个时间值添加⼀⾏来扩展分⾯⽹格:

sns.factorplot(x='day', y='tip_pct', row='time', col='smoker', kind='bar', data=tips[tips.tip_pct < 1])

factorplot⽀持其它的绘图类型,你可能会⽤到。例如,盒图(它可以显示中位数,四分位数,和异常值)就是⼀个有⽤的可视化类型(⻅下图):

#盒图 sns.factorplot(x='tip_pct', y='day', kind='box', data=tips[tips.tip_pct < 0.5])

使⽤更通⽤的seaborn.FacetGrid类,你可以创建⾃⼰的分⾯⽹格。请查阅seaborn的⽂档(https://seaborn.pydata.org/)。

其它的Python可视化工具

与其它开源库类似,Python创建图形的⽅式⾮常多(根本罗列不完)。⾃从2010年,许多开发⼯作都集中在创建交互式图形以便在Web上发布。利⽤⼯具Boken(https://bokeh.pydata.org/en/latest/)和Plotly(https://github.com/plotly/plotly.py),现在可以创建动态交互图形,⽤于⽹⻚浏览器。 对于创建⽤于打印或⽹⻚的静态图形,我建议默认使⽤matplotlib和附加的库,⽐如pandas和seaborn。对于其它数据可视化要求,学习其它的可⽤⼯具可能是有⽤的。我⿎励你探索绘图的⽣态系统,因为它将持续发展。

最新回复(0)