资讯专栏INFORMATION COLUMN

用 Matplotlib 库生成动画图表

不知名网友 / 1509人阅读

摘要:相对于静态图表,人类总是容易被动画和交互式图表所吸引。可以使用轻松生成图表直方图功率谱,条形图,错误图表,散点图等。然而,也有一些方面落后于同类的库。动画使用一组固定的对象。稍后将用数据对行对象进行填充。现在用将它们转换为动画。

翻译:疯狂的技术宅
https://towardsdatascience.co...


更多文章请关注微信公众号:硬核智能


动画是一种展示现象的有趣方式。相对于静态图表,人类总是容易被动画和交互式图表所吸引。在描述多年来的股票价格、过去十年的气候变化、季节性和趋势等时间序列数据时,动画更有意义,因为我们可以看到特定的参数是怎样随时间变化的。

上面的图是雨滴的模拟并且已经使用 Matplotlib 库实现,该库是一个广为人知的祖父级别的 python 可视化包。 Matplotlib 通过对 50 个散点的比例和透明度进行设置来模拟雨滴。今天,Python 拥有大量强大的可视化工具,如 Plotly、Bokeh、Altair等等。这些库能够实现最先进的动画和交互特性。尽管如此,本文的目的是强调这个库的另一个方面,这个方面没有人进行过太多的探索,这就是动画


概述

Matplotlib 是一个广受欢迎的 Python 2D 绘图库。很多人都是从 Matplotlib 开始数据可视化之旅的。可以使用matplotlib轻松生成图表、直方图、功率谱,条形图,错误图表,散点图等。它还与 Pandas 和 Seaborn 等库无缝集成,创造出更加复杂的可视化效果。

matplotlib 的优点是:

它的设计类似于 MATLAB,因此很容易在在两者之间切换。

在后端进行渲染。

可以重现任何图表(需要一点努力)。

已经存在了十多年,拥有庞大的用户群。

然而,也有一些方面 Matplotlib 落后于同类的库。

Matplotlib 有一个过于冗长的规则 API。

有时候风格很差。

对 Web 和交互式图表的支持不佳。

对于大型复杂数据而言通常很慢。

这份复习资料是来自 Datacamp 的 Matplotlib 小抄,你可以通过它来提高自己的基础知识。


动画

Matplotlib 的 animation 基类负责处理动画部分。它提供了一个构建动画功能的框架。使用下面两个接口来实现:

FuncAnimation 通过重复调用函数 func 来产生动画。

ArtistAnimation: 动画使用一组固定的 Artist 对象。

但是,在这两个接口中,FuncAnimation 是最方便使用的。你可以通过阅读文档 得到的更多信息,因为我们只关注 FuncAnimation 工具。

要求

安装 numpymatplotlib

要将动画保存为 mp4 或 gif,需要安装 ffmpegimagemagick

准备好之后,我们就可以在 Jupyter note 中开始创建第一个动画了。可以从 Github 得到本文的代码。

基本动画:移动的正弦波

我们先用 FuncAnimation 创建一个在屏幕上移动的正弦波的动画。动画的源代码来自 Matplotlib 动画教程。首先看一下输出,然后我们会分析代码以了解幕后的原理。

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
plt.style.use("seaborn-pastel")


fig = plt.figure()
ax = plt.axes(xlim=(0, 4), ylim=(-2, 2))
line, = ax.plot([], [], lw=3)

def init():
    line.set_data([], [])
    return line,
def animate(i):
    x = np.linspace(0, 4, 1000)
    y = np.sin(2 * np.pi * (x - 0.01 * i))
    line.set_data(x, y)
    return line,

anim = FuncAnimation(fig, animate, init_func=init,
                               frames=200, interval=20, blit=True)

anim.save("sine_wave.gif", writer="imagemagick")

在第(7-9)行中,我们只需在图中创建一个带有单个轴的图形窗口。然后创建一个空的行对象,它实际上是动画中要修改的对象。稍后将用数据对行对象进行填充。

在第(11-13)行中,我们创建了 init 函数,它将使动画开始。 init 函数对数据进行初始化并设置轴限制。

在第(14-18)行中,我们最终定义了动画函数,该函数将帧编号( i )作为参数并创建正弦波(或任何其他动画),这取决于 i 的值。此函数返回一个已修改的绘图对象的元组,它告诉动画框架哪些部分应该属于动画。

在第 20 行中,我们创建了实际的动画对象。 blit 参数确保只重绘那些已经改变的图块。

这是在 Matplotlib 中创建动画的基本方法。通过对代码进行一些调整,可以创建有趣的可视化图表。接下来看看更多的可视化案例。


一个不断增长的线圈

同样,在 GeeksforGeeks 中有一个很好的例子。现在让我们在 matplotlib 的 animation 类的帮助下创建一个缓慢展开的动圈。该代码非常类似于正弦波图,只需稍作调整即可。

import matplotlib.pyplot as plt 
import matplotlib.animation as animation 
import numpy as np 
plt.style.use("dark_background")

fig = plt.figure() 
ax = plt.axes(xlim=(-50, 50), ylim=(-50, 50)) 
line, = ax.plot([], [], lw=2) 

# initialization function 
def init(): 
    # creating an empty plot/frame 
    line.set_data([], []) 
    return line, 

# lists to store x and y axis points 
xdata, ydata = [], [] 

# animation function 
def animate(i): 
    # t is a parameter 
    t = 0.1*i 
    
    # x, y values to be plotted 
    x = t*np.sin(t) 
    y = t*np.cos(t) 
    
    # appending new points to x, y axes points list 
    xdata.append(x) 
    ydata.append(y) 
    line.set_data(xdata, ydata) 
    return line, 
    
# setting a title for the plot 
plt.title("Creating a growing coil with matplotlib!") 
# hiding the axis details 
plt.axis("off") 

# call the animator     
anim = animation.FuncAnimation(fig, animate, init_func=init, 
                            frames=500, interval=20, blit=True) 

# save the animation as mp4 video file 
anim.save("coil.gif",writer="imagemagick") 


实时更新图表

在绘制动态数量(如库存数据,传感器数据或任何其他时间相关数据)时,实时更新的图表会派上用场。我们绘制了一个简单的图表,当有更多数据被输入系统时,该图表会自动更新。下面让我们绘制一家假想公司在一个月内的股票价格。

# importing libraries
import matplotlib.pyplot as plt
import matplotlib.animation as animation


fig = plt.figure()
# creating a subplot 
ax1 = fig.add_subplot(1,1,1)

def animate(i):
    data = open("stock.txt","r").read()
    lines = data.split("
")
    xs = []
    ys = []
   
    for line in lines:
        x, y = line.split(",") # Delimiter is comma    
        xs.append(float(x))
        ys.append(float(y))
    
    ax1.clear()
    ax1.plot(xs, ys)

    plt.xlabel("Date")
    plt.ylabel("Price")
    plt.title("Live graph with matplotlib")    
    
    
ani = animation.FuncAnimation(fig, animate, interval=1000) 
plt.show()

现在,打开终端并运行 python 脚本。你将得到如下图所示的图表,该图表会自动更新:

这里的间隔是 1000 毫秒或一秒。


3D 图动画

创建 3D 图形是很常见的,但如果我们想要为这些图形的视角设置动画,该怎么办呢?我们的想法是更改摄像机视图,然后用每个生成的图像来创建动画。在 Python Graph Gallery 上有一个很好的例子。

在与 jupyter notebook 相同的目录中创建名为 volcano 的文件夹。所有图片文件都将存储在这里,然后将在动画中使用。

# library
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

# Get the data (csv file is hosted on the web)
url = "https://python-graph-gallery.com/wp-content/uploads/volcano.csv"
data = pd.read_csv(url)

# Transform it to a long format
df=data.unstack().reset_index()
df.columns=["X","Y","Z"]

# And transform the old column name in something numeric
df["X"]=pd.Categorical(df["X"])
df["X"]=df["X"].cat.codes

# We are going to do 20 plots, for 20 different angles
for angle in range(70,210,2):

# Make the plot
    fig = plt.figure()
    ax = fig.gca(projection="3d")
    ax.plot_trisurf(df["Y"], df["X"], df["Z"], cmap=plt.cm.viridis, linewidth=0.2)

    ax.view_init(30,angle)

    filename="Volcano/Volcano_step"+str(angle)+".png"
    plt.savefig(filename, dpi=96)
    plt.gca()

这将会在 Volcano 文件夹中创建多个 PNG 文件。现在用 ImageMagick 将它们转换为动画。打开终端并切换到 Volcano 目录下输入以下命令:

convert -delay 10 Volcano*.png animated_volcano.gif


使用 Celluloid 模块创建的动画

Celluloid 是一个Python模块,它简化了在 matplotlib 中创建动画的过程。这个库创建一个 matplotlib 图,并从中再创建一个 Camera。然后重新处理数据,并在创建每个帧后,用 camera 拍摄快照。最后创建包含所有帧的动画。

安装
pip install celluloid

以下是使用 Celluloid 模块的一些示例。

Minimal
from matplotlib import pyplot as plt
from celluloid import Camera

fig = plt.figure()
camera = Camera(fig)
for i in range(10):
    plt.plot([i] * 10)
    camera.snap()
animation = camera.animate()
animation.save("celluloid_minimal.gif", writer = "imagemagick")

Subplot
import numpy as np
from matplotlib import pyplot as plt
from celluloid import Camera

fig, axes = plt.subplots(2)
camera = Camera(fig)
t = np.linspace(0, 2 * np.pi, 128, endpoint=False)
for i in t:
    axes[0].plot(t, np.sin(t + i), color="blue")
    axes[1].plot(t, np.sin(t - i), color="blue")
    camera.snap()
    
animation = camera.animate()  
animation.save("celluloid_subplots.gif", writer = "imagemagick")

Legend
import matplotlib
from matplotlib import pyplot as plt
from celluloid import Camera

fig = plt.figure()
camera = Camera(fig)
for i in range(20):
    t = plt.plot(range(i, i + 5))
    plt.legend(t, [f"line {i}"])
    camera.snap()
animation = camera.animate()
animation.save("celluloid_legends.gif", writer = "imagemagick")


总结

动画有助于突出显示无法通过静态图表轻松传达的某些功能。尽管如此,不必要的过度使用有时会使事情复杂化,应该明智地使用数据可视化中的每个功能以产生最佳效果。

更多文章请关注微信公众号:硬核智能

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19995.html

相关文章

  • Matplotlib 生成动画图表

    摘要:相对于静态图表,人类总是容易被动画和交互式图表所吸引。可以使用轻松生成图表直方图功率谱,条形图,错误图表,散点图等。然而,也有一些方面落后于同类的库。动画使用一组固定的对象。稍后将用数据对行对象进行填充。现在用将它们转换为动画。 翻译:疯狂的技术宅https://towardsdatascience.co... showImg(https://segmentfault.com/img...

    call_me_R 评论0 收藏0
  • 快速入门 Matplotlib 绘图

    摘要:概述是使用开发的一个绘图库,是界进行数据可视化的首选库。可以通过图形示例来快速浏览所有支持的图形。最后,调用把绘制好的图形显示出来。对应于三个参数,表示行,表示列,表示位置。因此,表示在图表中总共有个图形,当前新增的图形添加到位置。 showImg(https://segmentfault.com/img/bV6EPD?w=542&h=130); 概述 Matplotlib 是使用 P...

    Hujiawei 评论0 收藏0
  • Python绘制精美图表之双柱形图

    摘要:图表是比干巴巴的表格更直观的表达,简洁有力。当我们想关注比数值本身更多的信息像数值的变化对比或异常,图表就非常有用了。把数值转化为图片要依赖第三方库的帮忙,在之中最好的图表库叫。 图表是比干巴巴的表格更直观的表达,简洁、有力。工作中经常遇到的场景是,有一些数值需要定时的监控,比如服务器的连接数、活跃用户数、点击某个按钮的人数,并且通过邮件或者网页展示出来。当我们想关注比数值本身更多的信...

    beita 评论0 收藏0
  • Python学习之路14-生成数据

    摘要:小结本篇主要讲述了如何生成数据集以及如何对其进行可视化如何使用创建简单的图表如果使用散点图来探索随机漫步过程如何使用创建直方图,以及如何使用直方图来探索同时掷两个面数不同的骰子的结果。 《Python编程:从入门到实践》笔记。从本篇起将用三篇的篇幅介绍如何用Python进行数据可视化。 1. 前言 从本篇开始,我们将用三篇的篇幅来初步介绍如何使用Python来进行数据可视化操作。本篇的...

    wanglu1209 评论0 收藏0
  • Python学习笔记:数据可视化(一)

    摘要:当数据发生变化时,这种演变过程随之发生。是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 showImg(https://segmentfault.com/img/bVbnkP1?w=751&h=558); python相关 基础概念 数据:离散的,客观事实的数字表示 信息:处理后的数据,为实际问题提供答案   - 为数据提供一种关系或一个关联后,数据就成了信...

    Crazy_Coder 评论0 收藏0

发表评论

0条评论

不知名网友

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<