python 动态可视化_Python实现酷炫的动态交互式数据可视化,附代码!

(关注公众号AI新视野,发送‘资料’二字,免费获取50G人工智能视频教程!)

本文介绍如何创建交互式图表和小组件,使用python做数据可视化。涉及的python库有:Plotly, Bokeh, nbinteract等。

数据可视化

分析数据集的时候,数据可视化是很重要的一步。如果做得好的话,有很多好处:帮我们更深入的理解那些隐藏在数据集中的动态变化

这些分析工作,能让你后续的机器学习更高效

让别人更容易的理解我们的数据

在这篇文章中,我将用一些实际的例子和有趣的可视化方法,来向你介绍python中最常用的数据可视化库。文中提到的代码你可以在github中找到:

github 地址[1]

Matplotlib

Matplotlib 可能是最广为人知的Python数据可视化库。举个例子,我将向你介绍如何创建一张PCA方差GIF图。

首先,我们必须使用Seaborn加载Iris数据集并且执行PCA。成功之后,我们将通过从轴上改变不同角度观察,绘制20张PCA方差图。为了去创建3D的PCA结果图,我把 The Python Graph Gallery当作参考。

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from mpl_toolkits.mplot3d import Axes3D

import seaborn as sns

import os

from sklearn.decomposition import PCA

import imageio

df = sns.load_dataset('iris')

my_dpi=96

plt.figure(figsize=(480/my_dpi, 480/my_dpi), dpi=my_dpi)

# Keep the 'specie' column appart + make it numeric for coloring

df['species']=pd.Categorical(df['species'])

my_color=df['species'].cat.codes

df = df.drop('species', 1)

# Run The PCA

pca = PCA(n_components=3)

pca.fit(df)

# Store results of PCA in a data frame

result=pd.DataFrame(pca.transform(df), columns=['PCA%i' % i for i in range(3)], index=df.index)

# 20 plots, for 20 different angles

for angle in range(70,210,2):

# Plot initialisation

fig = plt.figure()

ax = fig.add_subplot(111, projection='3d')

ax.scatter(result['PCA0'], result['PCA1'], result['PCA2'], c=my_color, cmap="Set2_r", s=60)

# make simple, bare axis lines through space:

xAxisLine = ((min(result['PCA0']), max(result['PCA0'])), (0, 0), (0,0))

ax.plot(xAxisLine[0], xAxisLine[1], xAxisLine[2], 'r')

yAxisLine = ((0, 0), (min(result['PCA1']), max(result['PCA1'])), (0,0))

ax.plot(yAxisLine[0], yAxisLine[1], yAxisLine[2], 'r')

zAxisLine = ((0, 0), (0,0), (min(result['PCA2']), max(result['PCA2'])))

ax.plot(zAxisLine[0], zAxisLine[1], zAxisLine[2], 'r')

ax.view_init(30,angle)

# label the axes

ax.set_xlabel("PC1")

ax.set_ylabel("PC2")

ax.set_zlabel("PC3")

ax.set_title("PCA Iris Dataset")

filename='PCA/PCA_angle'+str(angle)+'.png'

plt.savefig(filename, dpi=96)

最终,我们可以通过下面的这个函数从我们的20个图中生成GIF。

def make_gif(input_folder, save_filepath):

episode_frames = []

time_per_step = 0.25

for root, _, files in os.walk(input_folder):

file_paths = [os.path.join(root, file) for file in files]

#sorted by modified time

file_paths = sorted(file_paths, key=lambda x: os.path.getmtime(x))

episode_frames = [imageio.imread(file_path)

for file_path in file_paths if file_path.endswith('.png')]

episode_frames = np.array(episode_frames)

imageio.mimsave(save_filepath, episode_frames, duration=time_per_step)

make_gif('./PCA/', './PCA/PCA.gif')

获得的结果应该和图1的结果相同。这种相同的机制可以应用于其他很多应用,就像:动画分布,轮廓和机器学习模型。

在Matplotlib中制作动画图形的另一种方法是使用Matplotlib动画API。这个API可以制作一些简单的动画和实时图标。一些案例可以在这里[2]找到。

Celluloid

可以使用Celluloid库来简化Matplotlib中的动画。通过创建一个摄像头来实现,该摄像头的目标是在每次图形的某个参数发生变化时拍摄该图形的快照。然后,所有这些瞬间存储的图片组合在一起以生成动画。

在下面的示例中,为每个循环迭代生成快照,并使用animate() 函数创建动画。

from celluloid import Camera

import numpy as np

import matplotlib.pyplot as plt

fig, axes = plt.subplots(2)

camera = Camera(fig)

t = np.linspace(0, 5 * np.pi, 128, endpoint=False)

t2 = np.linspace(0, 1 * np.pi, 128, endpoint=False)

for i in t2:

axes[0].plot(t, np.cos(t/2 + i), color='b')

axes[1].plot(t2, np.sin(t2 - i), color='b')

camera.snap()

animation = camera.animate()

animation.save('celluloid_example.gif', writer = 'imagemagick')

然后还可以使用ImageMagick将生成的动画存储为GIF。生成的动画如图2所示。

Plotly

Plotly是一个基于plotly.js的开源Python库。 Plotly有两种不同的模式:在线和离线。通过该库,我们可以使用在线模式制作无限制的离线模式图表和最多25个在线图表。在安装Plotly时,需要注册到他们的网站并获得API密钥才能开始(而不能像文中其它库一样仅仅使用pip install)。

在这篇文章中,我将向您介绍一个使用离线模式的示例,以便在很长一段时间内绘制特斯拉股票市场的高价和低价。在这里[3]可以找到我用于此示例的数据。

首先,我们需要导入所需的Plotly库。

接下来,我导入数据集并对其进行预处理,以便实现最终的绘图。在本例中,要确保用于绘图的列是正确的数据类型,日期的格式是(YYYY-MM-DD)。为此,我将高低价格列转换为双数据类型,将日期列转换为字符串格式。随后,我将日期列从DD/MM/YYYY格式转换为YYYY/MM/DD格式,最后转换为YYYY-MM-DD格式。

import plotly.graph_objs as go

from plotly.offline import init_notebook_mode, iplot

init_notebook_mode(connected=True)

import plotly.plotly as py

import plotly

import pandas as pd

import datetime

df = pd.read_csv("TSLA.csv")

df['date'] = df['date'].astype('str')

df['high'] = df['high'].astype('double')

df['low'] = df['low'].astype('double')

date2 = []

for i in df['date']:

new_date = datetime.datetime.strptime(i, "%d/%m/%Y").strftime("%Y-%m-%d")

date2.append(new_date)

df['date'] = df['date'].str.replace('/', '-')

df['date'] = date2

df.fillna(0)

df.head()

最后,我使用Plotly库来生成特斯拉股票市场高价和低价的时间序列表。感谢Plotly,这个表将是可互动的。将光标移动到时间轴的任意一点我们都可以得到高价和低价,并且选择按钮和滑块可以改变问哦们想要关注的时间范围。

trace_high = go.Scatter(

x=df.date,

y=df['high'],

name = "TSLA High",

line = dict(color = '#17BECF'),

opacity = 0.8)

trace_low = go.Scatter(

x=df.date,

y=df['low'],

name = "TSLA Low",

line = dict(color = '#7F7F7F'),

opacity = 0.8)

data = [trace_high,trace_low]

layout = dict(

title='Time Series with Rangeslider',

xaxis=dict(

rangeselector=dict(

buttons=list([

dict(count=1,

label='1m',

step='month',

stepmode='backward'),

dict(count=6,

label='6m',

step='month',

stepmode='backward'),

dict(step='all')

])

),

rangeslider=dict(

visible = True

),

type='date'

)

)

fig = dict(data=data, layout=layout)

iplot(fig, filename = "Time Series with Rangeslider")

plotly.offline.plot(fig, filename='Plotly_Stock.html')

图4展示了最终结果。Plotly官方文档提供了大量有关如何更好的使用这个库的例子,他们中的一些可以在这里[4]找到。

Bokeh

Bokeh库同时支持Python和JavaScript。它的大多数图形,交互和小部件都可以用Python实现,但是在一些情况中也要用到JavaScript。

当使用Bokeh时,通过将一个图层堆叠到另一个图层上来构建图形。我们一开始创建一个图形,然后我们在上面添加元素(字形)。图形可以时任何的形式和形状(例如线,条,圆),取决于我们尝试去制作的图形。

当使用Bokeh创建图形时,会自动生成一些工具来绘制图形。他们有:Bokeh文档的参考链接,平移,框缩放,滚轮缩放,保存选项和重置图形按钮(和Plotly类似)。

作为一个实际的例子,我将介绍如何使用和Plotly一样的数据来绘制交互式时间序列图。

对于此演示,将绘制四个不同的时间序列(高/低/开盘价和收盘价)并且将创建四个复选框。用这种方式,使用者可以使用选中或取消复选框来让四个轴中 的任何一个从图中消失。

举个例子,为了实现复选框功能,使用JavaScript而不是Python。

import pandas as pd

import numpy as np

from bokeh.plotting import figure

from bokeh.io import output_file, show, output_notebook

from bokeh.models import CustomJS

from bokeh.models.widgets import CheckboxGroup

from bokeh.layouts import row

from bokeh.palettes import Viridis4

from bokeh.models.annotations import Title, Legend

df = pd.read_csv("TSLA.csv")

df['date'] = pd.to_datetime(df['date'], format='%d/%m/%Y')

p = figure(x_axis_type='datetime', plot_width=800)

aline = p.line(df['date'], df['high'], line_width=2, color=Viridis4[0])

bline = p.line(df['date'], df['low'], line_width=2, color=Viridis4[1])

cline = p.line(df['date'], df['open'], line_width=2, color=Viridis4[2])

dline = p.line(df['date'], df['close'], line_width=2, color=Viridis4[3])

p.yaxis.axis_label = 'Price'

p.xaxis.axis_label = 'Time Span'

legend = Legend(items=[

("High Price", [aline]),

("Low Price", [bline]),

("Open Price", [cline]),

("Close Price", [dline])

], location=(0, 450))

t = Title()

t.text = 'Tesla Stock Market Analysis'

p.title = t

p.add_layout(legend, 'left')

checkboxes = CheckboxGroup(labels=list(['High Price', 'Low Price', 'Open Price',

'Close Price']), active=[0, 1, 2, 3])

callback = CustomJS(code="""aline.visible = false; // aline and etc.. are

bline.visible = false; // passed in from args

cline.visible = false;

dline.visible = false;

// cb_obj is injected in thanks to the callback

if (cb_obj.active.includes(0)){aline.visible = true;}

// 0 index box is aline

if (cb_obj.active.includes(1)){bline.visible = true;}

// 1 index box is bline

if (cb_obj.active.includes(2)){cline.visible = true;}

// 2 index box is cline etc...

if (cb_obj.active.includes(3)){dline.visible = true;}""",

args={'aline': aline, 'bline': bline, 'cline': cline, 'dline': dline})

checkboxes.js_on_click(callback)

output_file('Tesla_Stock_Widget.html')

show(row(p, checkboxes))

图5展示了结果图

如上面的代码展示的,这个图还可以另存为HTML文件。这个相同的选项也可以在Plotly中使用。如果你有兴趣测试你自己对于Plotly和Bokeh的了解,他们都可以在这里[5]找到。

Plotly和Bokeh都可以被另外用作Python的仪表板框架,创建出非常惊人的结果。

Seaborn

Seaborn 是一个建立在Matplotlib之上的python库,用于制作统计图表。根据Seaborn官网的介绍:如果Matplotlib"尝试让简单的事情变简单,让复杂的事情成为可能",那么Seaborn就尝试制作一些明确的定义,让复杂的事情也变得简单

在这里,我不会给你详细的介绍使用Seaborn的例子,如果你正想要了解Seaborn,推荐你查看这个:Seaborn 例子汇总[6]

在下面的例子中,我首先使用Seaborn加载了Iris 数据集[7],然后制作了pair-plot。

import seaborn as sns

sns.set(style="ticks")

df = sns.load_dataset("iris")

sns.pairplot(df, hue="species")

一个pair-plot是一个函数,用来展现数据集中一对对变量的图形化摘要。它用到了散点图和代表了一个个矩阵对角线的单变量分布。具体的结果展现在图6:

nbinteract

nbinteract可以让我们在Jupiter Notebook上创建交互式小部件。如果需要,也可以用HTML导出这些小部件。可以在这里[8]找到nbinteract在线实现的实例。

作为一个简单的实现,这里将创建一个下拉菜单。更改所有汽车数量的选择或者实时更新车主的名字。(图7)

from ipywidgets import interact

import numpy as np

import pandas as pd

from matplotlib import pyplot as plt

import nbinteract as nbi

def cars(name, number):

return '{} has {} cars!'.format(name, number)

interact(cars, name='Nemo', number={'Zero': 0, 'Two': 2,

'Three': 3, 'Ten': 10});

Additional库

除了已经提到的库外,Pygal[9]和Altair[10]也是常用的Python库。他们都提供了与之前类似的图,但是他们被可以用来创建其他种类的图形,例如:金字塔图,树状图,地图和甘特图。

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值