社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

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

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

 快速高效学会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
 
563 次点击