python报表设计⼯具_8个好看⼜实⽤Python可视化⼯具包,再
也不怕做不出图表了!...
编译:机器之⼼
作者:Aaron Frederick喜欢⽤ Python 做项⽬的⼩伙伴不免会遇到这种情况:做图表时,⽤哪种好看⼜实⽤的可视化⼯具包呢?之前⽂章⾥出现过漂亮的图表时,也总有读者在后台留⾔问该图表时⽤什么⼯具做的。下⾯,作者介绍了⼋种在 Python 中实现的可视化⼯具包,其中有些包还能⽤在其它语⾔中。快来试试你喜欢哪个?
⽤ Python 创建图形的⽅法有很多,但是哪种⽅法是最好的呢?当我们做可视化之前,要先明确⼀些关于图像⽬标的问题:你是想初步了解数据的分布情况?想展⽰时给⼈们留下深刻印象?也许你想给某⼈展⽰⼀个内在的形象,⼀个中庸的形象?
本⽂将介绍⼀些常⽤的 Python 可视化包,包括这些包的优缺点以及分别适⽤于什么样的场景。这篇⽂章只扩展到 2D 图,为下⼀次讲 3D 图和商业报表(dashboard)留了⼀些空间,不过这次要讲的包中,许多都可以很好地⽀持 3D 图和商业报表。
00.Matplotlib、Seaborn 和 Pandas
把这三个包放在⼀起有⼏个原因:⾸先 Seaborn 和 Pandas 是建⽴在 Matplotlib 之上的,当你在⽤ Seaborn 或 Pandas 中的 df.plot()时,⽤的其实是别⼈⽤ Matplotlib 写的代码。因此,这些图在美化⽅⾯是相似的,⾃定义图时⽤的语法也都⾮常相似。
当提到这些可视化⼯具时,我想到三个词:探索(Exploratory)、数据(Data)、分析(Analysis)。这些包都很适合第⼀次探索数据,但要做演⽰时⽤这些包就不够了。
Matplotlib 是⽐较低级的库,但它所⽀持的⾃定义程度令⼈难以置信(所以不要简单地将其排除在演⽰所⽤的包之外!),但还有其它更适合做展⽰的⼯具。
Matplotlib 还可以选择样式(style selection),它模拟了像 ggplot2 和 xkcd 等很流⾏的美化⼯具。下⾯是我⽤ Matplotlib 及相关⼯具所做的⽰例图:
在处理篮球队薪资数据时,我想出薪资中位数最⾼的团队。为了展⽰结果,我将每个球队的⼯资⽤颜⾊标成条形图,来说明球员加⼊哪⼀⽀球队才能获得更好的待遇。import seaborn as sns
import matplotlib.pyplot as plt
color_order = ['xkcd:cerulean', 'xkcd:ocean',
'xkcd:black','xkcd:royal purple',
'xkcd:royal purple', 'xkcd:navy blue',
'xkcd:powder blue', 'xkcd:light maroon',
'xkcd:lightish blue','xkcd:navy']
sns.barplot(x=top10.Team,
y=top10.Salary,
palette=color_order).set_title('Teams with Highest Median Salary')
plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0))
第⼆个图是回归实验残差的 Q-Q 图。这张图的主要⽬的是展⽰如何⽤尽量少的线条做出⼀张有⽤的图,当然也许它可能不那么美观。import matplotlib.pyplot as plt
import scipy.stats as stats
#model2 is a regression model
log_resid = model2.predict(X_test)-y_test
plt.title("Normal Q-Q plot")
plt.show()
最终证明,Matplotlib 及其相关⼯具的效率很⾼,但就演⽰⽽⾔它们并不是最好的⼯具。
你可能会问,「Aaron,ggplot 是 R 中最常⽤的可视化包,但你不是要写 Python 的包吗?」。⼈们已经在 Python 中实现了 ggplot2,复制了这个包从美化到语法的⼀切内容。
在我看过的所有材料中,它的⼀切都和 ggplot2 很像,但这个包的好处是它依赖于 Pandas Python 包。不过 Pandas Python 包最近弃⽤了⼀些⽅法,导致 Python 版本不兼容。
如果你想在 R 中⽤真正的 ggplot(除了依赖关系外,它们的外观、感觉以及语法都是⼀样的),我在另外⼀篇⽂章中对此进⾏过讨论。
也就是说,如果你⼀定要在 Python 中⽤ ggplot,那你就必须要安装 0.19.2 版的 Pandas,但我建议你最好不要为了使⽤较低级的绘图包⽽降低 Pandas 的版本。
ggplot2(我觉得也包括 Python 的 ggplot)举⾜轻重的原因是它们⽤「图形语法」来构建图⽚。基本前提是你可以实例化图,然后分别添加不同的特征;也就是说,你可以分别对标题、坐标轴、数据点以及趋势线等进⾏美化。
下⾯是 ggplot 代码的简单⽰例。我们先⽤ ggplot 实例化图,设置美化属性和数据,然后添加点、主题以及坐标轴和标题标签。#All Salaries
ggplot(data=df, aes(x=season_start, y=salary, colour=team)) +
geom_point() +
theme(legend.position="none") +
labs(title = 'Salary Over Time', x='Year', y='Salary ($)')
02.Bokeh
Bokeh 很美。从概念上讲,Bokeh 类似于 ggplot,它们都是⽤图形语法来构建图⽚,但 Bokeh 具备可以做出专业图形和商业报表且便于使⽤的界⾯。为了说明这⼀点,我根据 538 Masculinity Survey 数据集写了制作直⽅图的代码:import pandas as pd
from bokeh.plotting import figure
from bokeh.io import show
# is_masc is a one-hot encoded dataframe of responses to the question:
# "Do you identify as masculine?"
#Dataframe Prep
counts = is_masc.sum()
resps = lumns
#Bokeh
p2 = figure(title='Do You View Yourself As Masculine?',
x_axis_label='Response',
y_axis_label='Count',
x_range=list(resps))
p2.vbar(x=resps, top=counts, width=0.6, fill_color='red', line_color='black')
counts.plot(kind='bar')
⽤ Bokeh 表⽰调查结果
红⾊的条形图表⽰ 538 个⼈关于「你认为⾃⼰有男⼦汉⽓概吗?」这⼀问题的答案。9~14 ⾏的 Bokeh 代码构建了优雅且专业的响应计数直⽅图——字体⼤⼩、y 轴刻度和格式等都很合理。
我写的代码⼤部分都⽤于标记坐标轴和标题,以及为条形图添加颜⾊和边框。在制作美观且表现⼒强的图⽚时,我更倾向于使⽤ Bokeh ——它已经帮我们完成了⼤量美化⼯作。
⽤ Pandas 表⽰相同的数据
蓝⾊的图是上⾯的第 17 ⾏代码。这两个直⽅图的值是⼀样的,但⽬的不同。在探索性设置中,⽤ Pandas 写⼀⾏代码查看数据很⽅便,但Bokeh 的美化功能⾮常强⼤。
Bokeh 提供的所有便利都要在 matplotlib 中⾃定义,包括 x 轴标签的⾓度、背景线、y 轴刻度以及字
好看的留言体(⼤⼩、斜体、粗体)等。下图展⽰了⼀些随机趋势,其⾃定义程度更⾼:使⽤了图例和不同的颜⾊和线条。
Bokeh 还是制作交互式商业报表的绝佳⼯具。
03.Plotly
Plotly ⾮常强⼤,但⽤它设置和创建图形都要花费⼤量时间,⽽且都不直观。在⽤ Plotly 忙活了⼤半个上午后,我⼏乎什么都没做出来,⼲脆直接去吃饭了。我只创建了不带坐标标签的条形图,以及⽆法删掉线条的「散点图」。Ploty ⼊门时有⼀些要注意的点:安装时要有API 秘钥,还要注册,不是只⽤ pip 安装就可以;
Plotly 所绘制的数据和布局对象是独⼀⽆⼆的,但并不直观;
图⽚布局对我来说没有⽤(40 ⾏代码毫⽆意义!)
但它也有优点,⽽且设置中的所有缺点都有相应的解决⽅法:你可以在 Plotly ⽹站和 Python 环境中编辑图⽚;
⽀持交互式图⽚和商业报表;
Plotly 与 Mapbox 合作,可以⾃定义地图;
很有潜⼒绘制优秀图形。
以下是我针对这个包编写的代码:#plot 1 - barplot
# **note** - the layout lines do nothing and trip no errors
data = [go.Bar(x=team_am,
y=team_ave_df.turnovers_per_mp)]
layout = go.Layout(
title=go.layout.Title(
text='Turnovers per Minute by Team',
xref='paper',
x=0
)
,
xaxis=go.layout.XAxis(
title = go.layout.xaxis.Title(
family='Courier New, monospace',
size=18,
color='#7f7f7f'
)
)
),
yaxis=go.layout.YAxis(
title = go.layout.yaxis.Title(
text='Average Turnovers/Minute',
font=dict(
family='Courier New, monospace',
size=18,
color='#7f7f7f'
)
)
),
autosize=True,
hovermode='closest')
py.iplot(figure_or_data=data, layout=layout, filename='jupyter-plot', sharing='public', fileopt='overwrite')
#plot 2 - attempt at a scatterplot
data = [go.Scatter(x=player_year.minutes_played,
y=player_year.salary,
marker=go.scatter.Marker(color='red',
size=3))]
layout = go.Layout(title="test",
xaxis=dict(title='why'),
yaxis=dict(title='plotly'))
py.iplot(figure_or_data=data, layout=layout, filename='jupyter-plot2', sharing='public')
[Image: image.png]
表⽰不同 NBA 球队每分钟平均失误数的条形图。
表⽰薪⽔和在 NBA 的打球时间之间关系的散点图
总体来说,开箱即⽤的美化⼯具看起来很好,但我多次尝试逐字复制⽂档和修改坐标轴标签时却失败了。但下⾯的图展⽰了 Plotly 的潜
Plotly 页⾯上的⼀些⽰例图
04.Pygal
Pygal 的名⽓就不那么⼤了,和其它常⽤的绘图包⼀样,它也是⽤图形框架语法来构建图像的。由于绘图⽬标⽐较简单,因此这是⼀个相对简单的绘图包。使⽤ Pygal ⾮常简单:实例化图⽚;
⽤图⽚⽬标属性格式化;
⽤ figure.add() 将数据添加到图⽚中。
我在使⽤ Pygal 的过程中遇到的主要问题在于图⽚渲染。必须要⽤ render_to_file 选项,然后在 web 浏览器中打开⽂件,才能看见我刚刚构建的东西。
最终看来这是值得的,因为图⽚是交互式的,有令⼈满意⽽且便于⾃定义的美化功能。总⽽⾔之,这个包看起来不错,但在⽂件的创建和渲染部分⽐较⿇烦。
05.Networkx
虽然 Networkx 是基于 matplotlib 的,但它仍是图形分析和可视化的绝佳解决⽅案。图形和⽹络不是我的专业领域,但 Networkx 可以快速简便地⽤图形表⽰⽹络之间的连接。以下是我针对⼀个简单图形构建的不同的表⽰,以及⼀些从斯坦福 SNAP 下载的代码(关于绘制⼩型 Facebook ⽹络)。
我按编号(1~10)⽤颜⾊编码了每个节点,代码如下:options = {
'node_color' : range(len(G)),
'node_size' : 300,
'width' : 1,
'with_labels' : False,
'cmap' : lwarm
}
nx.draw(G, **options)
⽤于可视化上⾯提到的稀疏 Facebook 图形的代码如下:import itertools
import networkx as nx
import matplotlib.pyplot as plt
f = open('data/facebook/1684.circles', 'r')
circles = [line.split() for line in f]
f.close()
network = []
for circ in circles:
cleaned = [int(val) for val in circ[1:]]
network.append(cleaned)
G = nx.Graph()
for v in network:
G.add_nodes_from(v)