Python大数据分析5:立体图绘制

本节主要介绍一些基本的三维图形绘制方法。三维图形表现为立体形状,一般至少三组数据才能实现图形元素的表现,相对来讲,显示复杂度较高。

我们先来搭一个基本框架。

import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3D

plt.subplot(projection=’3d’)

plt.show()

这里的subplot函数就是设置当前绘图环境为三维,同时需要导入必要的Axes3D类型。

这个就是三维绘图坐标空间,右下角会及时显示当前鼠标位于的空间坐标,

拖拽还能实现自由三维旋转。

我们先从线性图开始,绘制由线段组成的三维折线。为了能介绍清楚,我们先从一个简单例子说明起:

x = (0, 0, 1, 4, 5)

y = (1, 1, 1, 1, 2)

z = (2, 0, 3, 4, 5)

plt.plot(x, y, z)

plt.show()

这些折线的关键在于点,因此需要我们给出这些点的三维坐标,我们可以定义三个轴的坐标值,分别保存为三个列表,然后设置到plot中即可。

从图中可以看到,每个列表都是一个维度的数据,列表的长度就是点的个数,相应的线的个数应该是点的个数减一。

我们仍然以这一章一直在使用的股票数据为例。这次我们首先按照年、月分组,并统计

import pandas as pd

frame = pd.read_csv('C:\\temp\\股票数据.csv', encoding='GBK')
frame = frame.set_index('日期')
frame.index = pd.to_datetime(frame.index)
results = frame[['收盘价']].groupby([frame.index.year, frame.index.month]).mean()
print(results.index.codes[0])
print(results.index.codes[1])
print(results['收盘价'])

这个分组过程并不复杂,关键是如何获取分组后两个分组条件列,这里我们使用了codes属性,为0的就是第一个分组条件,即年,以此类推,为1的就是第二个分组条件,即月。此时,分组数据本身的大小意义不是很大,因此此时都会自动换成了数字序列。

然后我们就以这三个数据列来表达三维信息,

plt.subplot(projection=’3d’)

plt.plot(results.index.codes[0], results.index.codes[1], results[‘收盘价’])

plt.show()

当然,目前的结果似乎没有很好的展示效果,

通过旋转调整,可以看出随着年度的不断推移,月份不断从1到12再到1,就会产生明显的折线,并且平均收盘价不断呈现下降趋势。

而且,在早期一年当中的大起大落想象非常明显,后期一年当中的起伏相对变低。这也体现了这种三维分析的特点,往往可以进行更多维度的多角度观察。

接下来我们看看三维散点图。一般而言,三维线性图意义往往不大,除非结合时序关系,否则点与点之间的连线无法说明实质的意义。相对而言,散点图就更为常见,只需绘制点即可。

首先我们先取得收盘价、换手率、成交笔数三个数据按照年月汇总的平均值:

results = frame.groupby([frame.index.year, frame.index.month]).agg(val1=(‘收盘价’, ‘mean’), val2=(‘换手率’, ‘mean’), val3=(‘成交笔数’, ‘mean’))

print(results)

然后还是调用scatter函数实现:

ax = plt.subplot(projection=’3d’)

ax.scatter(results[‘val1’], results[‘val2’], results[‘val3’])

plt.show()

请注意,这里不能使用plt的scatter函数,因为它是二维散点图,如果要三维,需要理由plt的subplot函数返回当前绘图环境后再调用scatter,这个可以支持。

在图中旋转图形可以看出,大部分换手率都集中于2前后,

而且随着收盘价的不断增长,更易于出现成交笔数变大的趋势。

柱状图也可以进行三维绘制。比如可以按照年份,将每年的各个月统计数据分别做成一张柱状图,多次依次绘制后,就会形成三维效果:

results = frame[[‘收盘价’]].groupby([frame.index.year, frame.index.month]).mean()

plt.bar(results.index.codes[1], results[‘收盘价’], zs=results.index.codes[0])

plt.show()

其中,前两个分别表示在其中一个二维平面上传统的柱状图,分别是横轴月份,纵轴收盘价,最后一个zs参数表示第三个维度,即年份。

效果虽然看的出来,但是颜色并不能很好的区分。

为此,可以根据月份或者年份、甚至收盘价来设置不同的颜色:

import matplotlib.cm as cm

plt.bar(results.index.codes[1], results[‘收盘价’], zs=results.index.codes[0],

        color=cm.ScalarMappable().to_rgba(results.index.codes[0]))

plt.show()

这里使用年度作为区分颜色标准,

从中可以看出各个年份的不同数据情况,仍然不同年份升降趋势并不相同,但是总体随着年份而收盘价总体逐渐下降。

与此类似的还有一个3D版本的柱状图:

ax = plt.subplot(projection=’3d’)

ax.bar3d(x=results.index.codes[1], y=results.index.codes[0], z=0, dx=1, dy=1, dz=results[‘收盘价’], color=cm.ScalarMappable().to_rgba(results.index.codes[0]))

plt.show()

它是subplot函数返回类型的方法,参数设置略微复杂些,其中可以x、y、z分别是每个方柱的底部点的坐标,为了底部对齐,我们把z设置为0。后面的dx和dy分别表示每个方块的宽度和厚度,而高度则可以定义为收盘价等统计数据。

效果差不多,但是立体感更强。

发表评论

邮箱地址不会被公开。 必填项已用*标注