专栏首页AI科技大本营的专栏12个案例教你用Python玩转数据可视化

12个案例教你用Python玩转数据可视化

作者 | 伊凡·伊德里斯(Ivan Idris),曾是Java和数据库应用开发者,后专注于Python和数据分析领域,致力于编写干净、可测试的代码。他还是《Python Machine Learning By Example》《NumPy Cookbook》等书的作者,在工程实践和书籍撰写方面都非常有经验。(本文摘编自《Python数据分析实战》,经出版方授权发布。)

来源 | 大数据(ID:hzdashuju)

编辑 | Jane

【导读】相比于科学,数据分析更像是一门艺术。创建样式优美的数据可视化是这个艺术中不可缺少的部分。然而,某些人认为优美的,也会有人觉得难以接受。和艺术类似,随着数据分析的快速演变,人们的观念和品味也一直在变化。但是总的来说没有人是绝对正确和错误的。

作为一个数据艺术家以及有经验的Python程序员,我们可以从 matplotlib、Seaborn、Bokeh 和 ggplot 这些库里面选择一些来使用。

一、图形化安斯库姆四重奏

安斯库姆四重奏(Anscombe's Quartet)是一个经典案例,它可以说明为什么可视化是很重要的。四重奏包含了四组统计特性一致的数据。每个数据集有一些x值以及相对应的y值,我们将在一个IPython Notebook中列出这些指标。如果你绘制出这些数据集,你将发现这些图表截然不同。

  • 操作步骤

在本节你需要执行如下操作:

(1)由如下导入开始:

1import pandas as pd 
2import seaborn as sns 
3import matplotlib.pyplot as plt 
4import matplotlib as mpl 
5from dautil import report 
6from dautil import plotting 
7import numpy as np 
8from tabulate import tabulate

(2)定义以下函数来计算某一数据集中 x 和 y 的均值和方差、相关系数,以及斜率和每个数据集的线性拟合的截距:

 1def aggregate():
 2    df = sns.load_dataset("anscombe")
 3
 4    agg = df.groupby('dataset')\ 
 5        .agg([np.mean, np.var])\ 
 6        .transpose()
 7    groups = df.groupby('dataset')
 8
 9    corr = [g.corr()['x'][1] for _, g in groups]
10    builder = report.DFBuilder(agg.columns)
11    builder.row(corr)
12
13    fits = [np.polyfit(g['x'], g['y'], 1) for _, g in groups] 
14    builder.row([f[0] for f in fits]) 
15    builder.row([f[1] for f in fits]) 
16    bottom = builder.build(['corr', 'slope', 'intercept'])
17
18    return df, pd.concat((agg, bottom))

(3)下面这个函数返回一个字符串,这个字符串有一部分是Markdown,有一部分是重组的文字,有一部分是HTML,这主要是因为原生的Markdown不支持图表:

1def generate(table):
2    writer = report.RSTWriter()
3    writer.h1('Anscombe Statistics')
4    writer.add(tabulate(table, tablefmt='html', floatfmt='.3f'))
5    return writer.rst

(4)绘制数据并相应地与Seaborn的lmplot()函数线性拟合:

1def plot(df):
2    sns.set(style="ticks")
3    g = sns.lmplot(x="x", y="y", col="dataset",
4        hue="dataset", data=df,
5        col_wrap=2, ci=None, palette="muted", size=4,
6        scatter_kws={"s": 50, "alpha": 1})
7
8    plotting.embellish(g.fig.axes)

(5)展示一个统计数据的表格如下:

1df, table = aggregate()
2from IPython.display import display_markdown
3display_markdown(generate(table), raw=True)

下表中显示每个数据集的几乎相同的统计数据(我修改了IPython配置文件里的 custom.css,所以下表是有颜色的):

(6)以下几行代码绘制了数据集:

1%matplotlib inline
2plot(df)

请参见以下截图了解最终结果:

二、选择 Seaborn 的调色板

Seaborn 的调色板和 matplotlib 的颜色表类似。色彩可以帮助你发现数据中的模式,也是重要的可视化组成部分。Seaborn有很丰富的调色板,在这个示例中会将其可视化。

  • 操作步骤

(1)导入部分如下:

1import seaborn as sns
2import matplotlib.pyplot as plt
3import matplotlib as mpl
4import numpy as np
5from dautil import plotting

(2)使用以下函数帮助绘制调色板:

 1def plot_palette(ax, plotter, pal, i, label, ncol=1):
 2    n = len(pal)
 3    x = np.linspace(0.0, 1.0, n)
 4    y = np.arange(n) + i*n
 5    ax.scatter(x, y, c=x,
 6                cmap=mpl.colors.ListedColormap(list(pal)), 
 7                s=200)
 8    plotter.plot(x,y,label=label)
 9    handles, labels = ax.get_legend_handles_labels()
10    ax.legend(loc='best', ncol=ncol, fontsize=18)

(3)分类调色板(categorical palette)对于分类数据很有用,例如性别、血型等。以下函数可以绘制一些Seaborn的分类调色板:

1def plot_categorical_palettes(ax):
2    palettes = ['deep', 'muted', 'pastel', 'bright', 'dark','colorblind']
3    plotter = plotting.CyclePlotter(ax)
4    ax.set_title('Categorical Palettes')
5
6    for i, p in enumerate(palettes):
7        pal = sns.color_palette(p)
8        plot_palette(ax, plotter, pal, i, p, 4)

(4)圆形色彩系统(circular color system)通常用HLS(色度亮度饱和度,Hue Lightness Saturation)来取代RGB(红绿蓝Red Gree Blue)颜色空间。如果你有很多分类这将会很有用。以下函数可以使用HLS系统绘制调色板。

 1def plot_circular_palettes(ax):
 2    ax.set_title('Circular Palettes')
 3    plotter = plotting.CyclePlotter(ax)
 4
 5    pal = sns.color_palette("hls", 6)
 6    plot_palette(ax, plotter, pal, 0, 'hls')
 7
 8    sns.hls_palette(6, l=.3, s=.8)
 9    plot_palette(ax, plotter, pal, 1, 'hls l=.3 s=.8')
10
11    pal = sns.color_palette("husl", 6)
12    plot_palette(ax, plotter, pal, 2, 'husl')
13
14    sns.husl_palette(6, l=.3, s=.8)
15    plot_palette(ax, plotter, pal, 3, 'husl l=.3 s=.8') 

(5)Seaborn也有基于在线的ColorBrewer工具的调色板。用以下函数绘制出来:

http://colorbrewer2.org/

1def plot_brewer_palettes(ax):
2    ax.set_title('Brewer Palettes')
3    plotter = plotting.CyclePlotter(ax)
4
5    pal = sns.color_palette("Paired")
6    plot_palette(ax, plotter, pal, 0, 'Paired')
7
8    pal = sns.color_palette("Set2", 6)
9    plot_palette(ax, plotter, pal, 1, 'Set2')

(6)连续调色板(sequential palettes)对于数据范围很广的数据来说很有用,比如说有数量级差异的数据。用以下函数绘制出来:

 1def plot_sequential_palettes(ax):
 2    ax.set_title('Sequential Palettes')
 3    plotter = plotting.CyclePlotter(ax)
 4
 5    pal = sns.color_palette("Blues")
 6    plot_palette(ax, plotter, pal, 0, 'Blues')
 7
 8    pal = sns.color_palette("BuGn_r")
 9    plot_palette(ax, plotter, pal, 1, 'BuGn_r')
10
11    pal = sns.color_palette("GnBu_d")
12    plot_palette(ax, plotter, pal, 2, 'GnBu_d')
13
14    pal = sns.color_palette("cubehelix", 6)
15    plot_palette(ax, plotter, pal, 3, 'cubehelix')
(7)以下几行代码调用了我们之前定义的函数:
1%matplotlib inline
2
3fig, axes = plt.subplots(2, 2, figsize=(16, 12))
4plot_categorical_palettes(axes[0][0])
5plot_circular_palettes(axes[0][1])
6plot_brewer_palettes(axes[1][0])
7plot_sequential_palettes(axes[1][1])
8plotting.hide_axes(axes)
9plt.tight_layout()

请参见以下截图了解最终结果:

三、选择matplotlib的颜色表

matplotlib的颜色表最近受到了很多批评,因为它们可能会误导用户,但是在我看来大多数的颜色表还是不错的。默认的颜色表在matplotlib 2.0中有一些改进,可以在这里查看:

http://matplotlib.org/style_changes.html

当然,有些matplotlib的颜色表不支持一些不错的参数,比如说jet。在艺术中,就像数据分析中一样,几乎没有什么东西是绝对正确的,所以这里就交给读者去判断。

实际上,我觉得考虑如何解决印刷出版物以及各种各样的色盲问题是很重要的。在这个示例中我将用色条来可视化相对安全的颜色表。这里使用到的是matplotlib众多颜色表中的很小一部分。

  • 操作步骤

(1)导入部分如下:

1import matplotlib.pyplot as plt
2import matplotlib as mpl
3from dautil import plotting

(2)通过以下代码画出数据集:

 1fig, axes = plt.subplots(4, 4)
 2cmaps = ['autumn', 'spring', 'summer', 'winter',
 3         'Reds', 'Blues', 'Greens', 'Purples',
 4         'Oranges', 'pink', 'Greys', 'gray',
 5         'binary', 'bone', 'hot', 'cool']
 6
 7for ax, cm in zip(axes.ravel(), cmaps):
 8    cmap = plt.cm.get_cmap(cm)
 9    cb = mpl.colorbar.ColorbarBase(ax, cmap=cmap,
10                                    orientation='horizontal')
11    cb.set_label(cm)
12    ax.xaxis.set_ticklabels([])
13
14plt.tight_layout()
15plt.show()

请参见以下截图了解最终结果:

四、与 IPython Notebook 部件交互

简单来说,这些部件可以让你像在HTML表单里一样选择一些值,这包括滑块、下拉框、选择框等。正如你会读到的,这些部件非常方便将我们在第1章中提及的天气数据可视化。

  • 操作步骤

(1)导入部分如下:

1import seaborn as sns
2import numpy as np
3import pandas as pd
4import matplotlib.pyplot as plt
5from IPython.html.widgets import interact
6from dautil import data
7from dautil import ts

(2)加载数据同时请求内联图:

1%matplotlib inline
2df = data.Weather.load()

(3)定义以下函数,这个函数会显示气泡图:

 1def plot_data(x='TEMP', y='RAIN', z='WIND_SPEED', f='A', size=10,cmap='Blues'):
 2    dfx = df[x].resample(f)
 3    dfy = df[y].resample(f).mean()
 4    dfz = df[z].resample(f).mean()
 5
 6    bubbles = (dfz - dfz.min())/(dfz.max() - dfz.min())
 7    years = dfz.index.year
 8    sc = plt.scatter(dfx, dfy, s= size * bubbles + 9, c = years, 
 9                    cmap=cmap, label=data.Weather.get_header(z), 
10                    alpha=0.5)
11    plt.colorbar(sc, label='Year')
12
13    freqs = {'A': 'Annual', 'M': 'Monthly', 'D': 'Daily'}
14    plt.title(freqs[f] + ' Averages')
15    plt.xlabel(data.Weather.get_header(x))
16    plt.ylabel(data.Weather.get_header(y))
17    plt.legend(loc='best')

(4)通过以下代码调用我们刚刚定义的函数:

1vars = df.columns.tolist()
2freqs = ('A', 'M', 'D')
3cmaps = [cmap for cmap in plt.cm.datad if not cmap.endswith("_r")]
4cmaps.sort()
5interact(plot_data, x=vars, y=vars, z=vars, f=freqs,size=(100,700), cmap=cmaps)

(5)本示例需要上手操作一下来理解它的工作原理,下面是一个样例气泡图:

(6)定义另一个函数(和第(2)步中的程序同名,注释掉前一个),这个函数里我们将数据按照日或月进行分组:

 1def plot_data(x='TEMP', y='RAIN', z='WIND_SPEED', 
 2              groupby='ts.groupby_yday', 
 3              size=10, cmap='Blues'):
 4    if groupby == 'ts.groupby_yday':
 5        groupby = ts.groupby_yday
 6    elif groupby == 'ts.groupby_month':
 7        groupby = ts.groupby_month
 8    else:
 9        raise AssertionError('Unknown groupby ' + groupby)
10    dfx = groupby(df[x]).mean()
11    dfy = groupby(df[y]).mean()
12    dfz = groupby(df[z]).mean()
13    bubbles = (dfz - dfz.min())/(dfz.max() - dfz.min())
14    colors = dfx.index.values
15    sc = plt.scatter(dfx, dfy, s= size * bubbles + 9, 
16                     c = colors,cmap=cmap, 
17                     label=data.Weather.get_header(z), alpha=0.5)
18    plt.colorbar(sc, label='Day of Year')
19    by_dict = {ts.groupby_yday: 'Day of Year', ts.groupby_month: 'Month'}
20    plt.title('Grouped by ' + by_dict[groupby])
21    plt.xlabel(data.Weather.get_header(x))
22    plt.ylabel(data.Weather.get_header(y))
23    plt.legend(loc='best')

(7)用这段代码调用上述函数:

1groupbys = ('ts.groupby_yday', 'ts.groupby_month')
2interact(plot_data, x=vars, y=vars, z=vars, groupby=groupbys,
3size=(100,700), cmap=cmaps)

请参见以下截图了解最终结果:

我对这个图的第一印象是温度和风速似乎是正相关的。

五、查看散点图矩阵

如果你的数据集中变量不是很多,那么查看你数据所有的散点图是个不错的主意。通过调用Seaborn或者pandas的一个函数就可以做到。这些函数会展示一个矩阵的核密度估计图或对角线上的直方图。

  • 操作步骤

(1)导入部分如下:

1import pandas as pd
2from dautil import data
3from dautil import ts
4import matplotlib.pyplot as plt
5import seaborn as sns
6import matplotlib as mpl

(2)以下几行代码加载天气数据:

1df = data.Weather.load()
2df = ts.groupby_yday(df).mean()
3df.columns = [data.Weather.get_header(c) for c in df.columns]

(3)用Seaborn的pairplot()函数绘制图形,这个函数默认绘制对角线上的直方图:

1%matplotlib inline
2
3# Seaborn plotting, issues due to NaNs
4sns.pairplot(df.fillna(0))

结果如下所示:

(4)通过pandas的scatter_matrix()函数生成一个类似的图形,并请求对角线上的核密度估计图:

1sns.set({'figure.figsize': '16, 12'})
2mpl.rcParams['axes.linewidth'] = 9
3mpl.rcParams['lines.linewidth'] = 2
4plots = pd.scatter_matrix(df, marker='o', diagonal='kde')
5plt.show()

请参见以下截图了解最终结果:

六、通过 mpld3 使用 d3.js进行可视化

d3.js是在2011年推出的一个JavaScript 数据可视化库,我们可以在IPython Notebook里面使用这个库。我们将在一个普通matplotlib图上添加一个悬浮工具提示。这里我们会使用mpld3包作为使用d3.js的桥梁。这个示例不需要任何JavaScript编程。

1. 准备工作

通过以下命令安装mpld3 0.2:

1[sudo] pip install mpld3

2. 操作步骤

(1)由导入开始,并启用mpld3:

1%matplotlib inline
2import matplotlib.pyplot as plt
3import mpld3
4mpld3.enable_notebook()
5from mpld3 import plugins
6import seaborn as sns
7from dautil import data
8from dautil import ts

(2)加载天气数据并按照下面的方法将其绘制出来:

 1df = data.Weather.load()
 2df = df[['TEMP', 'WIND_SPEED']]
 3df = ts.groupby_yday(df).mean()
 4
 5fig, ax = plt.subplots()
 6ax.set_title('Averages Grouped by Day of Year')
 7points = ax.scatter(df['TEMP'], df['WIND_SPEED'],
 8                    s=30, alpha=0.3)
 9ax.set_xlabel(data.Weather.get_header('TEMP'))
10ax.set_ylabel(data.Weather.get_header('WIND_SPEED'))
11labels = ["Day of year {0}".format(i) for i in range(366)]
12tooltip = plugins.PointLabelTooltip(points, labels)
13
14plugins.connect(fig, tooltip)

高亮显示的那一行是工具栏。在下面的截图中,我们可以看到“Day of year 31”文本来自这个工具栏:

如你所见,在这个图形的底部,还有可以平移和缩放图形的装置。

七、创建热图

热图使用一组颜色在矩阵中可视化数据。最初,热图用于表示金融资产(如股票)的价格。Bokeh是一个Python包,可以在IPython Notebook中显示热图,或者生成一个独立的HTML文件。

1. 准备工作

Anaconda自带了 Bokeh 0.9.1。Bokeh的安装说明在:

http://bokeh.pydata.org/en/latest/docs/installation.html

2. 操作步骤

(1)导入部分如下:

1from collections import OrderedDict
2from dautil import data
3from dautil import ts
4from dautil import plotting
5import numpy as np
6import bokeh.plotting as bkh_plt
7from bokeh.models import HoverTool

(2)下面的函数加载了温度数据并按照年和月进行分组:

1def load():
2    df = data.Weather.load()['TEMP']
3    return ts.groupby_year_month(df)

(3)定义一个将数据重排成特殊的Bokeh结构的函数:

 1def create_source():
 2    colors = plotting.sample_hex_cmap()
 3    month = []
 4    year = []
 5    color = []
 6    avg = []
 7    for year_month, group in load():
 8        month.append(ts.short_month(year_month[1]))
 9        year.append(str(year_month[0]))
10        monthly_avg = np.nanmean(group.values)
11        avg.append(monthly_avg)
12        color.append(colors[min(int(abs(monthly_avg)) - 2, 8)])
13    source = bkh_plt.ColumnDataSource(data=dict(month=month, year=year, color=color, avg=avg))
14    return year, source

(4)定义一个返回横轴标签的函数:

1def all_years():
2    years = set(year)
3    start_year = min(years)
4    end_year = max(years)
5    return [str(y) for y in range(int(start_year), int(end_year),5)]

(5)定义一个绘制包含了悬浮工具栏的热图的函数:

 1def plot(year, source):
 2    fig = bkh_plt.figure(title="De Bilt, NL Temperature (1901 -2014)",
 3                                x_range=all_years(),
 4                                y_range=list(reversed(ts.short_months())),
 5                                toolbar_location="left",
 6                                tools="resize,hover,save,
 7                                pan,box_zoom,wheel_zoom")
 8    fig.rect("year", "month", 1, 1, source=source,
 9                color="color", line_color=None)
10
11    fig.xaxis.major_label_orientation = np.pi/3
12
13    hover = fig.select(dict(type=HoverTool))
14    hover.tooltips = OrderedDict([
15        ('date', '@month @year'),
16        ('avg', '@avg'),
17    ])
18
19    bkh_plt.output_notebook()
20    bkh_plt.show(fig)
21
22
23
24(6)调用上述定义的函数:
25
26
27
28year, source = create_source()
29plot(year, source)

请参见以下截图了解最终结果:

八、把箱线图、核密度图和小提琴图组合

小提琴图(Violin Plot)是一种组合盒图和核密度图或直方图的图形类型。Seaborn和matplotlib都能提供小提琴图。在这个示例中我们将使用Seaborn来绘制天气数据的Z分数(标准分数),分数的标准化并不是必需的,但是如果没有它的话小提琴图会很发散。

  • 操作步骤

(1)导入部分如下:

1import seaborn as sns
2from dautil import data
3import matplotlib.pyplot as plt

(2)加载天气数据并计算标准分数:

1df = data.Weather.load()
2zscores = (df - df.mean())/df.std()

(3)绘制标准分数的小提琴图:

1%matplotlib inline
2plt.figure()
3plt.title('Weather Violin Plot')
4sns.violinplot(zscores.resample('M').mean())
5plt.ylabel('Z-scores')

第一个小提琴图如下所示:

(4)绘制雨天和旱天相对风速的小提琴图:

1plt.figure()
2plt.title('Rainy Weather vs Wind Speed')
3categorical = df
4categorical['RAIN'] = categorical['RAIN'] > 0
5ax = sns.violinplot(x="RAIN", y="WIND_SPEED",data=categorical)
第二个小提琴图如下所示:

九、使用蜂巢图可视化网络图

蜂巢图(Hive Plot)是用于绘制网络图的可视化技术。在蜂巢图中我们将边缘绘制为曲线。我们根据属性对节点进行分组,并在径向轴上显示它们。

有些库在蜂窝图方面很专业。同时我们将使用API来划分Facebook用户的图形。

https://snap.stanford.edu/data/egonets-Facebook.html

这个数据属于斯坦福网络分析项目(Stanford Network Analysis Project,SNAP),它也提供了Python API,但是目前SNAP API还不支持Python 3。

1. 准备工作

Anaconda自带了NetworkX 1.9.1,它安装说明可见:

https://networkx.github.io/documentation/latest/install.html

同时我们还需要community包,安装地址:

https://bitbucket.org/taynaud/python-louvain

在PyPi上有一个同名的包,但是它和我们需要安装的没有任何关系。安装hiveplot包,这个包托管在:

https://github.com/ericmjl/hiveplot

1$ [sudo] pip install hiveplot 

本示例中使用的hiveplot版本是0.1.7.4。

2. 操作步骤

(1)导入部分如下所示:

1import networkx as nx
2import community
3import matplotlib.pyplot as plt
4from hiveplot import HivePlot
5from collections import defaultdict
6from dautil import plotting
7from dautil import dataython

(2)载入数据,创建一个NetworkX的Graph对象:

1fb_file = data.SPANFB().load()
2G = nx.read_edgelist(fb_file,create_using = nx.Graph(),nodetype = int)
3print(nx.info(G))

(3)分割图形对象并按照如下的方法创建一个nodes字典:

1parts = community.best_partition(G)
2nodes = defaultdict(list)
3
4for n, d in parts.items():
5    nodes[d].append(n)

(4)这个图形会非常大,所以我们将会创建三个边缘分组:

 1edges = defaultdict(list)
 2
 3for u, v in nx.edges(G, nodes[0]):
 4    edges[0].append((u, v, 0))
 5
 6for u, v in nx.edges(G, nodes[1]):
 7    edges[1].append((u, v, 1))
 8
 9for u, v in nx.edges(G, nodes[2]):
10    edges[2].append((u, v, 2))

(5)绘制这个图形大约需要6分钟:

1%matplotlib inline
2cmap = plotting.sample_hex_cmap(name='hot', ncolors=len(nodes.keys()))
3h = HivePlot(nodes, edges, cmap, cmap)
4h.draw()
5plt.title('Facebook Network Hive Plot')

等待一段时间,我们可以看到如下的图形:

十、显示地图

无论是处理全球数据还是本地数据,使用地图都是一个适合的可视化方式。我们需要用坐标来将数据定位到地图上,通常我们使用的就是这个点的经度和纬度。有很多现有的文件格式可以存储地理位置数据。

在这个示例中我们将会使用到特别的shapefile格式以及更常见的制表符分隔值(Tab Separated Values,TSV)格式。shapefile格式是由Esri公司创建的,并包含了三个必需的文件,它们的扩展名分别是.shp、.shx、.dbf。

.dbf文件包含了shapefile中每一个地理位置的额外信息的数据库。我们将使用的shapefile包含了国家边界、人口以及国内生产总值(Gross Domestic Product,GDP)的数据。我们可以使用cartopy库下载shapefile。

TSV文件包含了超过4000个城市的按时间序列的人口数据,可以在这里获得:

https://nordpil.com/resources/world-database-of-large-cities/

1. 准备工作

首先我们需要从源文件安装Proj.4,或者你也可以使用二进制版本安装:

https://github.com/OSGeo/proj.4/wiki

Proj.4的安装说明在:

https://github.com/OSGeo/proj.4

然后我们可以通过pip安装cartopy,本示例中使用到的是cartopy-0.13.0。或者你也可以通过下面的指令进行安装:

1$ conda install -c scitools cartopy

2. 操作步骤

(1)导入部分如下所示:

1import cartopy.crs as ccrs
2import matplotlib.pyplot as plt
3import cartopy.io.shapereader as shpreader
4import matplotlib as mpl
5import pandas as pd
6from dautil import options
7from dautil import data

(2)我们会使用颜色来做国家人口以及人口众多的城市的可视化。引入如下数据:

1countries = shpreader.natural_earth(resolution='110m',
2                                    category='cultural',
3                                    name='admin_0_countries')
4cities = pd.read_csv(data.Nordpil().load_urban_tsv(),sep='\t', encoding='ISO-8859-1')
5mill_cities = cities[cities['pop2005'] > 1000]

(3)使用以下代码画出地图,以及相应的颜色条,并将人口众多的城市标记在地图上:

 1%matplotlib inline
 2plt.figure(figsize=(16, 12))
 3gs = mpl.gridspec.GridSpec(2, 1,
 4                          height_ratios=[20, 1])
 5ax = plt.subplot(gs[0], projection=ccrs.PlateCarree())
 6
 7norm = mpl.colors.Normalize(vmin=0, vmax=2 * 10 ** 9)
 8cmap = plt.cm.Blues
 9ax.set_title('Population Estimates by Country')
10
11for country in shpreader.Reader(countries).records():
12   ax.add_geometries(country.geometry, ccrs.PlateCarree(),
13                     facecolor=cmap(
14                         norm(country.attributes['pop_est'])))
15
16plt.plot(mill_cities['Longitude'],
17         mill_cities['Latitude'], 'r.',
18         label='Populous city',
19         transform=ccrs.PlateCarree())
20
21options.set_mpl_options()
22plt.legend(loc='lower left')
23
24cax = plt.subplot(gs[1])
25cb = mpl.colorbar.ColorbarBase(cax,
26                               cmap=cmap,
27                               norm=norm,
28                               orientation='horizontal')
29
30cb.set_label('Population Estimate')
31plt.tight_layout()

十一、使用类ggplot2图

ggplot2 是在 R 语言用户群中很流行的数据可视化库。ggplot2的主要思想是在数据可视化的产出中包含多个图层。就像一个画家,我们从一个空的画布开始,紧接着一步步地添加图层。

通常我们使用rpy2来让Python接入R语言代码。然而,如果我们只是想使用ggplot2的话,用pyggplot库会显得更加方便。在这个示例中将实现三个国家的人口增长的可视化,使用的数据来自pandas上检索到的世界银行的数据。这些数据中包含各种指标和相关元数据。在这里可以下载到关于这些指标的描述:

http://api.worldbank.org/v2/en/topic/19?downloadformat=excel

我们可以认为世界银行的数据集是静态的。然而,类似的数据集经常发生变化,足以占用分析师所有的时间。更换指标的名字明显会影响代码,所以我决定通过joblib库来缓存数据。但是这个方法美中不足的是不能pickle所有的Python对象。

1. 准备工作

首先你需要有安装了ggplot2的R语言环境。如果你不是特别想使用ggplot2,或许你可以跳过这个示例。

R语言的主页是:

http://www.r-project.org/

ggplot2的文档:

http://docs.ggplot2.org/current/index.html

你可以通过pip安装pyggplot,我使用的是pyggplot-23。安装joblib,请浏览:

https://pythonhosted.org/joblib/installing.html

我的Anaconda中有joblib 0.8.4。

2. 操作步骤

(1)导入部分如下:

1import pyggplot
2from dautil import data

(2)通过以下代码加载数据:

1dawb = data.Worldbank()
2pop_grow = dawb.get_name('pop_grow')
3df = dawb.download(indicator=pop_grow, start=1984, end=2014)
4df = dawb.rename_columns(df, use_longnames=True)

(3)下面用我们新建的pandas对象DataFrame初始化pyggplot:

1p = pyggplot.Plot(df)

(4)添加条形图:

1p.add_bar('country', dawb.get_longname(pop_grow), color='year')

(5)翻转图表,使条形图指向右边并渲染

1p.coord_flip()
2p.render_notebook()

请参见以下截图了解最终结果:

十二、使用影响图高亮数据

类似于气泡图,影响图(influence plot)会考虑到单个数据点拟合、影响和杠杆之后的残差。残差的大小绘制在垂直轴上,并且可以标识数据点是异常值。为了更好地理解影响图,可以看下面的这些方程。

根据statsmodels文档,残差按标准偏差式(2.1)进行缩放,在式(2.2)中,n是观测点的数量,p是回归量。式(2.3)我们习惯称之为帽子矩阵(hat-matrix)。帽子矩阵的对角元素给出称为杠杆(leverage)的特殊度量,杠杆作为水平轴的量,可以标识出影响图的潜在影响。

在影响图中,影响会决定绘图点的大小。影响大的点往往具有高残差和杠杆。statsmodels可以使用Cook距离(Cook's distance)(见式(2.4))或者DFFITS(见式(2.5))来衡量影响值。

  • 操作步骤

(1)导入部分如下:

1import matplotlib.pyplot as plt
2import statsmodels.api as sm
3from statsmodels.formula.api import ols
4from dautil import data

(2)获取可用的国家的编码:

1dawb = data.Worldbank()
2countries = dawb.get_countries()[['name', 'iso2c']]

(3)从世界银行加载数据:

1population = dawb.download(indicator=[dawb.get_name('pop_grow'),
2                                      dawb.get_name('gdp_pcap'),
3                                      dawb.get_name('primary_education')],
4                           country=countries['iso2c'],
5                           start=2014,
6                           end=2014)
7population = dawb.rename_columns(population)
(4)定义一个普通最小二乘模型如下:
1population_model = ols("pop_grow ~ gdp_pcap + primary_education",
2                       data=population).fit()

(5)使用Cook距离描绘这个模型的影响图:

1%matplotlib inline
2fig, ax = plt.subplots(figsize=(19.2, 14.4))
3fig = sm.graphics.influence_plot(population_model, ax=ax, criterion="cooks")
4plt.grid()

请参见以下截图了解最终结果:

(本文为 AI大本营转载文章,转载请微信联系原作者)

本文分享自微信公众号 - AI科技大本营(rgznai100),作者:Ivan Idris

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-04-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 李彦宏:简单搜索永远没有广告;安全是自动驾驶第一天条

    在今天下午刚刚举办的2018数博会“人工智能:AI 生态加速未来”论坛中,百度董事长兼CEO李彦宏、中国科学院院士张钹、微软全球资深副总裁王永东等嘉宾分别发表了...

    AI科技大本营
  • CSDN受邀成为首批中国人工智能产业发展联盟特约媒体

    中国人工智能产业发展联盟媒体项目组成立会于2018年1月25日在京举行。会议由联盟办公室主任石霖主持。作为联盟的首批特约媒体,CSDN 成为媒体项目组成员之一。...

    AI科技大本营
  • 谷歌大脑深度学习从入门到精通视频课程[2.7]:训练神经网络——BP算法

    AI100 已经引入 Hugo Larochelle 教授的深度学习课程,会每天在公众号中推送一到两节课,并且对视频中的 PPT 进行讲解。课后,我们会设计一...

    AI科技大本营
  • 干货:12个案例教你用Python玩转数据可视化(建议收藏)

    导读:相比于科学,数据分析更像是一门艺术。创建样式优美的数据可视化是这个艺术中不可缺少的部分。然而,某些人认为优美的,也会有人觉得难以接受。和艺术类似,随着数据...

    华章科技
  • javascript基础之两种函数的定义方法

    wfaceboss
  • Java单体应用 - 项目实战(后台) - 03.后台账户管理 - 05.删除账户

    原文地址:http://www.work100.net/training/monolithic-project-iot-cloud-admin-manager-...

    光束云
  • 自己动手DIY一台2.4G简易频谱仪

    作为一名电子爱好者,自己动手制作一些简单的硬件小设备还是非常有趣的。我之前也是发布了《制作HackCube中的坎坎坷坷》。这次带来的是一个简易的频谱仪。

    FB客服
  • 部署Amoeba3.X实现Mysql读写

       Amoeba for Mysql软件,致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当SQL路由功能,专注于分布式数据库...

    py3study
  • Basemap系列教程:3D

    尽管很多人不喜欢3D地图,但是仍可以使用 Basemap 和 matplotlib mplot3d [注1] 工具绘制3D地图。

    bugsuse
  • 一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-实现字典的打印

    系列回顾          从上一篇文章一步一步教你使用AgileEAS.NET基础类库进行应用开发-WinForm应用篇-实例一个模块(商品字典)开始我带领大...

    魏琼东

扫码关注云+社区

领取腾讯云代金券