使用 Python 制作动画 3D 条形图 [英] Animated 3D bar-chart with Python

查看:92
本文介绍了使用 Python 制作动画 3D 条形图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在 3d 条形图中显示一些数据,z = f(x,y,t).我想让这个图表随时间变化/动画.

现在,我可以在任何给定时间 t 显示我的数据 z = f(x,y,t) 但我找不到重绘的方法图表自动显示下一时间步的数据.有没有办法做到这一点?

我尝试了一个简单的循环,但显然我只能看到最后一个时间步的数据.

这是我的代码的当前版本:

from mpl_toolkits.mplot3d 导入 Axes3D来自数学进口cos,罪过导入matplotlib.pyplot作为plt将numpy导入为np# z = f(x,t) 的仲裁函数def z_xt(x,t):返回30 * sin(5 * t)+ x ** 2 + 20#z = f(y,t)的仲裁函数def z_yt(y,t):返回 20*cos(2*t) + y**3/10 + 20# 叠加 z(x,y,t) = z(x,t) + z(y,t)def z_xyt(f_xt, f_yt):返回f_xt + f_yt# 时空域的定义nx = 9;dx = 1ny = 6;dy = 1nt = 10;dt = 1y,x = np.mgrid [slice(0,ny,dy),slice(0,nx,dx)]t_list = [针对范围(nt)中的t,取整(t(d * dt,2))]#包含每个时间步的解决方案的矩阵Z_xyt = [t_list中t的z_xyt(z_xt(x,t),z_yt(y,t))]# 在 3D 条形图中绘制数据无花果= plt.figure()ax = fig.add_subplot(111, 投影='3d')x_grid,y_grid = np.meshgrid(np.arange(nx),np.arange(ny))x_grid = x_grid.flatten()y_grid = y_grid.flatten()# 迭代时间并绘制相应的数据对于索引,t在枚举(t_list)中:# t_list[index] 时刻的 Z_xyt 数据z_data = Z_xyt [index] .flatten()# 绘制/实现每个时间步长的 3D 条形图数据bar_chart = ax.bar3d(x_grid, y_grid, np.zeros(len(z_data)), 1, 1, z_data)plt.draw()plt.show()

提前致谢!

解决方案

我终于找到了一种方法,通过将图表嵌入到 PyQt 窗口中(按照

I have to display some data, z = f(x,y,t), in a 3d bar-chart. I'd like to have this chart changing/animated with time.

For now, I can display my data z = f(x,y,t) for any given time t but I can't find a way to redraw the chart automatically to display the data of the next time step. Is there a way for doing this?

I tried with a simple loop but apparently I can only see the data for the last time step.

Here is the current version of my code:

from mpl_toolkits.mplot3d import Axes3D
from math import cos, sin
import matplotlib.pyplot as plt 
import numpy as np

# An arbitraty function for z = f(x,t)
def z_xt(x, t):
    return 30*sin(5*t) + x**2 + 20

# An arbitraty function for z = f(y,t)
def z_yt(y, t):
    return 20*cos(2*t) + y**3/10 + 20

# Superposition z(x,y,t) = z(x,t) + z(y,t)
def z_xyt(f_xt, f_yt):
    return f_xt+f_yt

# Definition of space and time domains
nx = 9;  dx = 1
ny = 6;  dy = 1
nt = 10; dt = 1
y, x   = np.mgrid[slice(0, ny, dy),slice(0, nx, dx)]
t_list = [round(t*dt,2) for t in range(nt)]

# The matrix that contains the solution for every time step
Z_xyt  = [z_xyt(z_xt(x, t), z_yt(y, t)) for t in t_list]

# Plot data in a 3D bar chart
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x_grid, y_grid = np.meshgrid(np.arange(nx), np.arange(ny))
x_grid = x_grid.flatten()
y_grid = y_grid.flatten()

# Iterate time and plot coresponding data
for index, t in enumerate(t_list):    
    # Z_xyt data at time t_list[index] 
    z_data = Z_xyt[index].flatten()

    # Draw/actualize 3D bar chart data for every time step                                     
    bar_chart = ax.bar3d(x_grid, y_grid, np.zeros(len(z_data)), 1, 1, z_data)
    plt.draw()

plt.show()

Thanks in advance!

解决方案

I finally found a way for doing it by embedding the chart in a PyQt window (following the instructions given in this post). The code proposed below generate a PyQt window in which the 3D bar-chart is displayed. The chart can be animated using a slider (time variations).

import sys
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from mpl_toolkits.mplot3d import Axes3D
from math import cos, sin
import matplotlib.pyplot as plt 
import numpy as np

# An arbitraty function for z = f(x,t)
def z_xt(x, t):
    return 30*sin(5*t) + x**2 + 20

# An arbitraty function for z = f(y,t)
def z_yt(y, t):
    return 20*cos(2*t) + y**3/10 + 20

# Superposition z(x,y,t) = z(x,t) + z(y,t)
def z_xyt(f_xt, f_yt):
    return f_xt+f_yt

# Definition of space and time domains
nx = 9;  dx = 1
ny = 6;  dy = 1
nt = 50; dt = 0.05
y, x   = np.mgrid[slice(0, ny, dy),slice(0, nx, dx)]
t_list = [round(t*dt,2) for t in range(nt)]

# The matrix that contains the solution for every time step
Z_xyt  = [z_xyt(z_xt(x, t), z_yt(y, t)) for t in t_list]

# Plot data in a 3D bar chart
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x_grid, y_grid = np.meshgrid(np.arange(nx), np.arange(ny))
x_grid = x_grid.flatten()
y_grid = y_grid.flatten()


class Window(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        # a figure instance to plot on
        self.figure = plt.figure()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # A slider to make time variations
        self.horizontalSlider = QtGui.QSlider(self)
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.valueChanged.connect(self.plot)
        self.horizontalSlider.setMinimum(0)
        self.horizontalSlider.setMaximum(t_list.__len__()-1)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.horizontalSlider)
        self.setLayout(layout)

        # Generate the chart for t=0 when the window is openned
        self.plot()

    def plot(self):
        # Read the slider value -> t = t_list[t_index]
        t_index = self.horizontalSlider.value()

        # Get the z-data for the given time index
        z_data = Z_xyt[t_index].flatten()

        # Discards the old chart and display the new one
        ax = self.figure.add_subplot(111,projection='3d')
        ax.hold(False)
        ax.bar3d(x_grid, y_grid, np.zeros(len(z_data)), 1, 1, z_data)

        # refresh canvas
        self.canvas.draw()


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    main = Window()
    main.show()

    sys.exit(app.exec_())

Graphically, the window looks like this:

这篇关于使用 Python 制作动画 3D 条形图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆