Py学习  »  Python

手把手教你学python第四课:数据可视化

与尔岩说 • 2 年前 • 630 次点击  

 快速高效学会python的终极奥义:过、抄、仿、改、调、看、练、创、悟


正文开始前,首先声明下,我也是半路出家非科班出身,所以可能代码的规范性和优雅性不够强,经常写一些我自己过了半小时就不认识的代码,写的目的也只是为了分享,大佬们求轻拍;


上一节课讲的是数据分析,分析和展示往往是一体的,在做了数据的统计归纳之后,如何用图表展示出来是非常重要的,专业做数据分析的爸爸们把这步称为eda,探索性数据分析~~也就是用图像刻画数据的规律,对于做金融的我们来说,更多的适用于把报表做的更好看一点,或者发现数据的一些特殊规律,所以本节还是比较独立的,有已经熟练掌握或者对画图不感兴趣的可以跳过~~


本次的代码分享还是两个部分,一块是常用包包的基本代码,这块主要是为了大家可以随时检索关键词然后抄代码的;另一块是通过一个案例让大家知道应该怎么具体应用,总体来说这块代码比较简单,要画什么图改改data改改格式设置就可以了,就不录视频了~~



01



常用包包及重要代码(保存下来随时抄)


matplotlib介绍

基本图形展现

使用plot函数,首先收藏链接:http://matplotlib.org/contents.html

%matplotlib inline
import matplotlib.pyplot as plt
plt.plot([1,3,2,4][1,3,2,7 ],'ro')
plt.ylabel('some numbers')
plt.axis([0, 6, 0, 20])
plt.show()

上面例子里的plot里的list规定了x和y,如果缺省一个则将视为y值,后面的‘ro’表示红色的圈圈,可以做修改;
axis()命令给定了坐标范围,格式是[xmin, xmax, ymin, ymax];
实际上,matplotlib不仅可以用于画向量,还可以用于画多维数据数组。

# evenly sampled time at 200ms intervals
t = np.arange(0., 5., 0.2)

# red dashes, blue squares and green triangles
plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.show()

格式设置

线形设置

有很多线的性质可供你设置:线宽,虚线格式,反锯齿补偿,等。进一步深入了解参数可以参见matplotlib.lines.Line2D

·我们可以通过'linewidth'来设置线宽,通过设定set_antialiased来确定是否消除锯齿

line = plt.plot([1,2,3,4], [1,4,9,16], '-', linewidth=2.0)
line.set_antialiased(False) # 关闭反锯齿

面我们都只画了一条线。这里,我们采用lines = plot(x1,y1,x2,y2)来画两条线。可以使用setp()命令,可以像MATLAB一样设置几条线的性质。setp可以使用python 关键词,也可用MATLAB格式的字符串。(plt.setp(lines))

lines = plt.plot([1,2,3,4], [1,4,9,16], [1,2,3,4], [16,5,6,2])
# use keyword args
plt.setp(lines, color='r', linewidth=2.0)
# or MATLAB style string value pairs
plt.setp(lines, 'color', 'r', 'linewidth', 2.0)

我们在作图中经常用到的性质都在以下列表中给出了:
线型包括

线型  描述
'-' 实线
'--' 虚线
'-.' 点划线
':' 点
'None', '', 不画

线标记包括

标记  描述
'o' 圆圈
'D' 钻石
'h' 六边形1
'H' 六边形2
'x' X
'', 'None' 不画
'8' 八边形
'p' 五角星
',' 像素点
'+' 加号
'.' 点
's' 正方形
'*' 星型
'd' 窄钻石
'v' 下三角
''>' 右三角
'^' 上三角

颜色 所有的颜色设置可以通过命令matplotlib.pyplot.colors()来查询

标记  颜色
'b' 蓝色
'g' 绿色
'r' 红色
'c' 蓝绿色
'm' 品红
'y' 黄色
'k' 黑色
'w' 白色

如果上面的颜色还是不够用,可以采用RGB3元组来定义,范围是0~1
比如:color = (0.3, 0.3, 0.4)
color可以被用在一系列和函数中,这里我们再title中改变color

修改坐标范围

默认情况下,坐标轴的最小值和最大值与输入数据的最小、最大值一致。也就是说,默认情况下整个图形都能显示在所画图片上,我们可以通过xlim(xmin, xmax)和ylim(ymin, ymax)来调整x,y坐标范围,见下:

xlim(-2.5, 2.5)
#设置y轴范围
ylim(-1, 1)
plt.plot(x, y1)

创建子图

你可以通过plt.figure创建一张新的图,plt.subplot来创建子图。subplot()指令包含numrows(行数), numcols(列数), fignum(图像编号),其中图像编号的范围是从1到行数 * 列数。在行数 * 列数<10时,数字间的逗号可以省略。

def f(t):
return np.exp(-t) * np.cos(2*np.pi*t)

t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)

plt.figure(1)
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')

plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
plt.show()

你可以多次使用figure命令来产生多个图,其中,图片号按顺序增加。这里,要注意一个概念当前图和当前坐标。所有绘图操作仅对当前图和当前坐标有效。通常,你并不需要考虑这些事,下面的这个例子为大家演示这一细节。

plt.figure(1)                # 第一张图
plt.subplot(211) # 第一张图中的第一张子图
plt.plot([1,2,3])
plt.subplot(212) # 第一张图中的第二张子图
plt.plot([4,5,6])


plt.figure(2) # 第二张图
plt.plot([4,5,6]) # 默认创建子图subplot(111)

plt.figure(1) # 切换到figure 1 ; 子图subplot(212)仍旧是当前图
plt.subplot(211) # 令子图subplot(211)成为figure1的当前图
plt.title('Easy as 1,2,3') # 添加subplot 211 的标题

添加文字

text()可以在图中的任意位置添加文字,并支持LaTex语法
xlable(), ylable()用于添加x轴和y轴标签
title()用于添加图的题目

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

# 数据的直方图
n, bins, patches = plt.hist(x, 50, normed=1, facecolor='g', alpha=0.75)
plt.xlabel('Smarts')
plt.ylabel('Probability')
#添加标题
plt.title('Histogram of IQ')
#添加文字
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.axis([40, 160, 0, 0.03])
plt.grid(True)
plt.show()

t0 = plt.text(0.35,0.5,'my text')
plt.setp(t0, color='b',fontsize=24)
t = plt.xlabel('my data', fontsize=14, color='red')

注释文本

在数据可视化的过程中,图片中的文字经常被用来注释图中的一些特征。使用annotate()方法可以很方便地添加此类注释。在使用annotate时,要考虑两个点的坐标:被注释的地方xy(x, y)和插入文本的地方xytext(x, y)

ax = plt.subplot(111)

t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = plt.plot(t, s, lw=2)

plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05),
)

plt.ylim(-2,2)
plt.show()

图例

一个图例包含多个图例项,每个图例项由图例说明和图例标签构成
图例标签
由彩色的图案构成,位于图例说明的左侧
图例说明
图例标签的说明文字
使用legend()函数可以自动添加图例

line_up, = plt.plot([1,2,3], label='Line 2')
line_down, = plt.plot([3,2,1], label='Line 1')
plt.legend(handles=[line_up, line_down])

有时候多个图例图例分别添加在不同位置使图有更强的可读性。可以通过多次调用legned()函数来实现。添加图例的位置可以用关键词loc来指定。

line1, = plt.plot([1,2,3], label="Line 1", linestyle='--')
line2, = plt.plot([3,2,1], label="Line 2", linewidth=4)

# Create a legend for the first line.
first_legend = plt.legend(handles=[line1], loc=1)

# Add the legend manually to the current Axes.
ax = plt.gca().add_artist(first_legend)

# Create another legend for the second line.
plt.legend(handles=[line2], loc=4)

plt.show()


seaborn介绍

参考以下链接:http://seaborn.pydata.org/tutorial.html

格式设置 Style management

seaborn有五种模版darkgrid, whitegrid, dark, white, and ticks可以选择

sns.set_style("whitegrid")
data = np.random.normal(size=(20, 6)) + np.arange(6) / 2
sns.boxplot(data=data);

可以用下面的命令去掉axes spines

sns.despine()

you can pass a dictionary of parameters to the rc argument of axes_style() and set_style()

sns.set_style("darkgrid", {"axes.facecolor": ".9"})
sinplot()

颜色设置
这里喜欢用的颜色:

渐变蓝色:
sns.palplot(sns.color_palette("Blues"))
渐变绿色:
sns.palplot(sns.color_palette("BuGn_r"))
渐变紫色:
sns.palplot(sns.cubehelix_palette(8))

颜色设置方法:

x, y = np.random.multivariate_normal([0, 0], [[1, -.5], [-.5, 1]], size=300).T
cmap = sns.cubehelix_palette(light=1, as_cmap=True)
sns.kdeplot(x, y, cmap=cmap, shade=True);

设置图像的大小和位置

f, ax = plt.subplots(figsize=(7, 3))
sns.countplot(y= "deck", data=titanic, color="c");

各类图像

分布图

单变量分布图

在画分布图的时候可以选择是否加阴影(就是下面的填充),可以选择是否按照什么分布fit,可以选择kde和hist

sns.distplot(x, bins=20, kde=False, rug=True,hist=False);
sns.kdeplot(x, bw=.2, label="bw: 0.2",shade=True, cut=0)
sns.distplot(x, kde=False, fit=stats.gamma);
两个变量关系图

从最简单的散点图开始:

sns.jointplot(x="x", y="y", data=df);

难一点的蜂窝图
x, y = np.random.multivariate_normal(mean, cov, 1000).T
with sns.axes_style("white"):
sns.jointplot(x=x, y=y, kind="hex", color="k");
以及密度核型图
sns.jointplot( x="x", y="y", data=df, kind="kde");

等高线图:

f, ax = plt.subplots(figsize=(6, 6))
sns.kdeplot(df.x, df.y, ax=ax)
sns.rugplot(df.x, color="g", ax=ax)
sns.rugplot(df.y, vertical=True, ax=ax);

还可以玩出花样:

g = sns.jointplot(x="x", y="y", data=df, kind="kde", color="m")
g.plot_joint(plt.scatter, c="w", s=30, linewidth=1, marker="+")
g.ax_joint.collections[0].set_alpha(0)
g.set_axis_labels("$X$", "$Y$");

pairplot

iris = sns.load_dataset("iris")
sns.pairplot(iris);

g = sns.PairGrid(iris)
g.map_diag(sns.kdeplot)
g.map_offdiag(sns.kdeplot, cmap="Blues_d", n_levels=6);

类别变量

sns.stripplot(x="day", y="total_bill", data=tips);
sns.swarmplot(x="day", y="total_bill", data=tips);
sns.swarmplot(x="total_bill", y="day", hue="time", data=tips);
sns.boxplot(x="day", y="total_bill", hue="time", data=tips);
sns.violinplot(x="total_bill", y="day", hue="time", data=tips);

可以将两个图叠加在一起

sns.violinplot(x="day", y="total_bill", data=tips, inner=None)
sns.swarmplot(x="day", y="total_bill", data=tips, color="w", alpha=.5);

对于图进行基本的统计:

sns.barplot(x="sex", y="survived", hue="class", data=titanic);
sns.countplot(x="deck", data=titanic, palette="Greens_d");
sns.pointplot(x="sex", y="survived", hue="class", data=titanic);

分面图:

sns.factorplot(x="day", y="total_bill", hue="smoker",
col="time", data=tips, kind="swarm");

线性关系图

sns.regplot(x="total_bill", y="tip", data=tips);
sns.lmplot(x="total_bill", y="tip", data=tips);


02



具体案例-使用pandas自带画图工具



下面具体举一个例子(翻译自kaggle网站,之前在第一节课找资源的时候有提到过的一个很重要的网站:https://www.kaggle.com/residentmario/welcome-to-data-visualization):


导入的数据结构如下


柱状图

首先使用pandas进行画图,观察数据结构,类别变量比较多,直接做一个柱状图,看到加利福尼亚产的红酒比其它所有区域都多,但是柱状图只能告诉绝对的数量,没办法告诉我们比例~

reviews['province'].value_counts().head(10).plot.bar()


因此接下来我们考虑下来找到比例:可以仍然使用条形图,条形图非常灵活,其高度可以代表任何东西,只要它是一个数字。每个条形都可以代表任何东西,只要它是一个类别。

在这种情况下,类别是名义类别:也就是没有多大意义的“纯”类别。名义分类变量包括国家、邮政编码、奶酪类型和月球着陆器等内容。


(reviews['province'].value_counts().head(10) / len(reviews)).plot.bar()

另一种是有序类别:是确实可以进行比较的事物,例如地震震级、具有一定数量公寓的住宅区以及当地熟食店的薯片袋大小。这里我们可以用分数高低来做类别。

reviews['points'].value_counts().sort_index().plot.bar()



线图与面积图




    
reviews['points'].value_counts().sort_index().plot.line()



reviews['points'].value_counts().sort_index().plot.area()



直方图

直方图看起来很简单,就像条形图。它基本上是!事实上,直方图是一种特殊的条形图,它将您的数据分成均匀的间隔,并用条形显示每个间隔中有多少行。唯一的分析差异是,不是每个条形代表单个值,而是代表一个值范围。 

然而,直方图有一个主要缺点,因为它们将空间分成均匀的间隔,所以它们不能很好地处理比较集中的数据,就只能显示出一个柱子~~

reviews[reviews['price'] < 200]['price'].plot.hist()


点状图

下图向我们展示了价格和积分之间的相关性较弱:也就是说,更昂贵的葡萄酒在评论时通常会获得更多积分。

reviews[reviews['price'] < 100].sample(100).plot.scatter(x='price', y='points')


为了有效利用此图,我们必须对数据进行下采样,仅从完整集中抽取 100 个点。这是因为朴素的散点图不能有效地处理映射到同一地点的点。例如,如果两种葡萄酒(均价 100 美元)的评分为 90,则将第二个酒过度绘制到第一个上,我们只在图中添加一个点。如果它只发生几次,这不是问题。但是有了足够多的点,分布开始看起来像一个无形的斑点,你只见树木不见森林:

reviews[reviews['price'] < 100].plot.scatter(x='price', y='points')

由于散点图在过度绘制方面的弱点,散点图最适用于相对较小的数据集以及具有大量唯一值的变量。有几种方法可以处理过度绘图。我们已经演示了一种方法:对点进行采样。另一个内置于 Pandas 的有趣方法是使用我们的下一个绘图类型,十六进制图。


Hexplot图

reviews[reviews['price'] < 100].plot.hexbin(x='price', y='points', gridsize=15)


此图中的数据与之前散点图中的数据直接可比,但它告诉我们的故事却大不相同。从这个六边形图中我们可以看到,Wine Magazine 评论的酒瓶聚集了大约 87.5 分和大约 20 美元。

通过查看散点图,我们没有看到这种效果,因为太多价格相似、评分相似的葡萄酒被过度绘制了。通过解决这个问题,这个 hexplot 为我们提供了一个更有用的数据集视图。


六边形图和散点图可以应用于区间变量和/或有序分类变量的组合。


堆积图

堆积条形图共享了单变量条形图的优点和缺点。它们最适用于名义分类变量或小序数分类变量。


wine_counts.plot.bar(stacked=True)



wine_counts.plot.area()


与单变量面积图一样,多变量区域图是指名义范畴或区间变量。


堆叠的情节在视觉上非常漂亮。然而,它们有两个主要的局限性。


第一个限制是,堆叠图中的第二个变量必须是一个变量,其可能值的数量非常有限(可能是有序的范畴,如此处所示)。五种不同类型的葡萄酒是一个很好的数字,因为它保持了结果的解释;八有时被称为建议的上限。许多数据集字段自然不适合这个标准,因此您必须像这里那样选择一组感兴趣的对象来“做”。


第二个限制是解释性。尽管它们容易制作,而且看起来也很漂亮,叠成的地块使区分具体价值非常困难。例如,看看上面的图,你能不能知道哪种酒的得分更高达87分:红色混合(紫色)、黑比诺(红色)或霞多丽(绿色)?其实很难说!


处理图的格式

用figsize控制大小,用color控制颜色,fontsize控制字体大小,ax设置标题等,despine控制边框的格式和线~~

import matplotlib.pyplot as pltimport seaborn as sns
ax = reviews['points'].value_counts().sort_index().plot.bar( figsize=(12, 6), color='mediumvioletred', fontsize=16)ax.set_title("Rankings Given by Wine Magazine", fontsize=20)sns.despine(bottom=True, left=True)



03



具体案例-使用seaborn画图工具


Countplot

sns.countplot(reviews['points'])


seaborn不需要我们通过数值计算为它塑造数据;countplot为我们聚合数据。

KDE plot

KDE是一种消除数据噪声的统计方法。它解决了折线图的一个重要的基本弱点:它会去除异常值或“中间值”,这将导致折线图突然下降。


例如,假设只有一种酒的价格是19.93美元,而几百种酒的价格是20.00美元。如果我们在一个折线图中绘制数值计数,我们的线会突然下降到1,然后又回到1000左右,形成一条奇怪的“锯齿状”线。为便于比较,下面显示的具有相同数据的折线图正好存在此问题!


注意,xxais是seaborn,kdeplot是正在绘制的变量(在本例中是price),而y轴是它发生的频率。


KDE图比折线图更能获得区间数据的“真实形状”。事实上,对于这样的数据,我建议总是使用它而不是折线图。

sns.kdeplot(reviews.query('price < 200').price)


然而,对于有序分类数据来说,这是一个更糟糕的选择。一个KDE图预计,如果有200个葡萄酒评级为85,400个评级为86,那么介于两者之间的值,比如85.5,应该平滑到介于两者之间的某个位置(比如说,300)。但是,如果两者之间的值不能出现(不允许葡萄酒评级为85.5),那么KDE图适合于不存在的东西。在这些情况下,请改用折线图。


KDE图也可以用于二维。

sns.kdeplot(reviews[reviews['price'] < 200].loc[:, ['price', 'points']].dropna().sample(5000))


像这样的二元KDE图是散点图和十六进制图的一个很好的替代品。它们解决了散点图和十六进制图所面临的相同的数据过度绘制问题,采用了不同但同样具有视觉吸引力的方式。但是,请注意,双变量KDE图的计算非常密集。在本例中,我们选取了5000个点作为样本,以保持计算时间的合理性。


Distplot

sns.distplot(reviews['points'], bins=10, kde=False)

sns.jointplot(x='price', y='points', data=reviews[reviews['price'] < 100])

Notice that this plot comes with some bells and whistles: a correlation coefficient is provided, along with histograms on the sides. These kinds of composite plots are a recurring theme in seaborn. Other than that, the jointplot is just like the pandas scatter plot.

As in pandas, we can use a hex plot (by simply passing kind='hex') to deal with overplotting:

sns.jointplot(x='price', y='points', data=reviews[reviews['price'] < 100], kind='hex',               gridsize=20)



Boxplot

df = reviews[reviews.variety.isin(reviews.variety.value_counts().head(5).index)]
sns.boxplot( x='variety', y='points', data=df)


上述分布的中心是箱线图中的“方框”。方框顶部是第75百分位,底部是第25百分位。换句话说,一半的数据分布在盒子里!中间的绿线是中间带。


图的另一部分“胡须”显示了分布中心以外的点的范围。超出此范围的单个圆是异常值。


这个箱线图告诉我们,尽管所有五种葡萄酒的评分大致相同,波尔多风格的葡萄酒往往比霞多丽葡萄酒的评分高一点。


箱线图非常适合总结许多数据集的形状。它们在计算能力方面也没有限制:你可以在绘图中放置尽可能多的方框,只要你觉得舒服就可以挤到页面上。


然而,它们只适用于区间变量和具有大量可能值的标称变量;他们假设您的数据大致是正态分布的(否则他们的设计就没有多大意义);它们不携带任何关于个人价值观的信息,只把分布当作一个整体。


我发现稍微高级一点的violinplot在大多数情况下更具视觉吸引力:


sns.violinplot(    x='variety',    y='points',    data=reviews[reviews.variety.isin(reviews.variety.value_counts()[:5].index)])


Subplot分图

fig, axarr = plt.subplots(2, 2, figsize=(12, 8))
reviews['points'].value_counts().sort_index().plot.bar( ax=axarr[0][0], fontsize=12, color='mediumvioletred')axarr[0][0].set_title("Wine Scores", fontsize=18)
reviews['variety'].value_counts().head(20).plot.bar( ax=axarr[1][0], fontsize=12, color='mediumvioletred')axarr[1][0].set_title("Wine Varieties", fontsize=18)
reviews['province'].value_counts().head(20).plot.bar( ax=axarr[1][1], fontsize=12, color='mediumvioletred')axarr[1][1].set_title("Wine Origins", fontsize=18)
reviews['price'].value_counts().plot.hist( ax=axarr[0][1], fontsize=12, color='mediumvioletred')axarr[0][1].set_title("Wine Prices", fontsize=18)
plt.subplots_adjust(hspace=.3)
import seaborn as snssns.despine()


Facet刻面

刻面是使数据可视化的最简单方法。


刻面是多变量的,因为在将一个(分类的)变量放在行中,另一个(分类的)变量放在列中之后,在常规绘图开始之前,我们已经有了两个变量。


刻面很容易,因为从绘制kdeplot到将它们网格化的转换非常简单。它不需要学习任何新的可视化技术。这些限制与您在内部使用的绘图相同。


然而,刻面确实有一些重要的限制。它只能用于将数据从单一或成对的分类变量中分离出来,这些变量的计算能力非常低,在网格中的维数超过五个左右,并且绘图变得太小(或涉及大量滚动)。此外,它还涉及到选择(或让Python)一个顺序来绘制,但是对于名义上的分类变量,这种选择是随意的,令人分心。


然而,刻面是工具箱中一个非常有用和适用的工具。

df = footballers[footballers['Position'].isin(['ST', 'GK'])]df = df[df['Club'].isin(['Real Madrid CF', 'FC Barcelona', 'Atlético Madrid'])]
g = sns.FacetGrid(df, row="Position", col="Club")g.map(sns.violinplot, "Overall")


既然我们理解了刻面,就有必要快速回顾一下seaborn pairplot函数。


pairplot是一种非常有用且广泛使用的seaborn方法,用于刻面变量(与变量值相反)。将正确形状的数据帧传递给它,它将返回变量值的网格化结果:

sns.pairplot(footballers[['Overall', 'Potential', 'Value']])


lmplot

import seaborn as sns
sns.lmplot(x='Attack', y='Defense', hue='Legendary', markers=['x', 'o'], fit_reg=False, data=pokemon)

heatmap plot相关系数

sns.heatmap(    pokemon.loc[:, ['HP', 'Attack', 'Sp. Atk', 'Defense', 'Sp. Def', 'Speed']].corr(),    annot=True)


parallel_coordinates

import pandas as pdfrom pandas.plotting import parallel_coordinates
p = (pokemon[(pokemon['Type 1'].isin(["Psychic", "Fighting"]))] .loc[:, ['Type 1', 'Attack', 'Sp. Atk', 'Defense', 'Sp. Def']] )
parallel_coordinates(p, 'Type 1')


04



具体案例-其它进阶画图工具


这里分享一个matplotilb的案例,为什么在进阶部分来讲呢,其实他的基本代码是很简单的,上手也快,所以就没有举例子,但是相比于pandas和seaborn她的定制化程度最高,其实可以画出很多复杂的图表,下面举一个例子;

matplotlib画状态切分图~~之前也有很多小伙伴感兴趣

银城路蓬蓬蓬,公众号:与尔岩说0524碎碎念 量化视角看利率之宏观周期判断
fig,ax1=plt.subplots(figsize=(20,7)) plt.plot(data['剩余流动性因子'],'black',label='剩余流动性因子') 


    
plt.legend(loc='lower left') ax1.set_ylabel('剩余流动性因子') ax2=ax1.twinx() plt.plot(data['通胀因子'],label='通胀因子') ax2.set_ylabel('通胀因子') plt.legend() dd=dd.dropna() con1=0 con2=0 con3=0 con4=0 for i in dd.index:     if dd.loc[i,'剩余流动性因子_上行概率']<0.5 and dd.loc[i,'通胀因子_上行概率']<0.5:         num=list(dd.index).index(i)+1         plt.axvspan(i,list(dd.index)[num],label="_"*con1+"通胀下行剩余流动性下行",alpha=0.3)         plt.legend()         con1=con1+1     if dd.loc[i,'剩余流动性因子_上行概率']>0.5 and dd.loc[i,'通胀因子_上行概率']<0.5:         num=list(dd.index).index(i)+1         plt.axvspan(i,list(dd.index)[num],label="_"*con2+"通胀下行剩余流动性上行",color='darkcyan',alpha=0.3)         plt.legend()         con2=con2+1     if dd.loc[i,'剩余流动性因子_上行概率']<0.5 and dd.loc[i,'通胀因子_上行概率']>0.5:         try:             num=list(dd.index).index(i)+1             plt.axvspan(i,list(dd.index)[num],label="_"*con3+"通胀上行剩余流动性下行",color='moccasin',alpha=0.3)         except:             print(i)         con3=con3+1     if dd.loc[i,'剩余流动性因子_上行概率']>0.5 and dd.loc[i,'通胀因子_上行概率']>0.5:         try:             num=list(dd.index).index(i)+1             plt.axvspan(i,list(dd.index)[num],label="_"*con4+"通胀上行剩余流动性上行",color='orange',alpha=0.3)             con4=con4+1         except:             print(i) plt.legend() 



到目前为止,在本教程中,我们一直在使用seaborn和pandas这两个围绕matplotlib设计的成熟库。这些库都专注于构建“静态”可视化:没有移动部分的可视化。当涉及到交互性和动画时,网络打开了许多可能性。有许多绘图库可以提供这些功能。


这里首先介绍plotly,这是一个开源的绘图库,它是这些库中最流行的一个。


from plotly.offline import init_notebook_mode, iplotinit_notebook_mode(connected=True)


import plotly.graph_objs as go
iplot([go.Scatter(x=reviews.head(1000)['points'], y=reviews.head(1000)['price'], mode='markers')])


此图表是完全交互式的。我们可以使用右上角的工具栏对数据执行各种操作:例如缩放和平移。当我们将鼠标悬停在数据点上时,会得到一个工具提示。我们甚至可以将绘图保存为PNG图像。


这张图表也显示了这个更奇特的绘图库的缺点。为了保持性能合理,我们必须将自己限制在数据集中的前1000个点。尽管这是必要的(为了避免过多的过度绘制),但重要的是要注意,一般来说,交互式图形比静态图形更需要大量的资源。更容易“最大化”你能显示多少数据点。


注意plotly API的“shape”。iplot获取打印对象列表并为您组合,打印组合的最终结果。这使得叠加图变得很容易。


作为另一个例子,这里有一个KDE图(plotly称为historogram2dcontour)和相同数据的散点图。

iplot([go.Histogram2dContour(x=reviews.head(500)['points'],                              y=reviews.head(500)['price'], 


    
                             contours=go.Contours(coloring='heatmap')),       go.Scatter(x=reviews.head(1000)['points'], y=reviews.head(1000)['price'], mode='markers')])

plotly公开了几种不同的API,其复杂性从低级到高级不等。iplot是最高级别的API,因此是最方便的通用API。


就我个人而言,我总是发现情节化的表面是其最令人印象深刻的特征(尽管这是最难弄清楚的特征之一):

df = reviews.assign(n=0).groupby(['points', 'price'])['n'].count().reset_index()df = df[df["price"] < 100]v = df.pivot(index='price', columns='points', values='n').fillna(0).values.tolist()iplot([go.Surface(z=v)])

df = reviews['country'].replace("US", "United States").value_counts()
iplot([go.Choropleth( locationmode='country names', locations=df.index.values, text=df.index, z=df.values)])

总而言之,plotly是一个功能强大、交互丰富的数据可视化库。它使我们能够生成比pandas和seaborn更有吸引力的图片。但是plotly网站上的office文档混合使用了不同的绘图功能,这使得使用起来比必须使用的更困难。


此外,重要的是要认识到什么时候交互性有用,什么时候不有用。最有效的绘图不需要使用悬停或工具提示来完成工作。因此,plotly虽然非常吸引人,但没那么实用大多数时候~~


如果大家需要更复杂的图表,这里也有推荐的工具~~就是百度开源的一个东东叫echarts,感兴趣的小伙伴可以一起交流,这里不做过多说明~~


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/115684
 
630 次点击