在收敛迭代期间更新 3d python 图 [英] updating a 3d python plot during a convergence iteration

查看:42
本文介绍了在收敛迭代期间更新 3d python 图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试创建一个绘图脚本,将我的数据绘制在两个 3d 结构(一个变量作为颜色)中,我在数据应该收敛的循环中使用这些结构.我想在每次迭代时更新该图,而不是创建一个新图.关于如何实现这一目标的任何想法?

I try to create a plotting script that plots my data in two 3d structures (with one variable as a color) that I use in a loop in which the data is supposed to converge. I would like to update the figure every iteration, instead of creating a new figure. Any ideas on how I can achieve this?

功能:

import matplotlib.pyplot as plt
import numpy as np

def colorplot_3D(network, color_variable_1, color_variable_2):

    net = network

    X, Y, Z = net['pore.coords'][net.Ps].T
    X_max, Y_max, Z_max = np.amax(X), np.amax(Y), np.amax(Z)

    plt.ion()
    fig = plt.figure()
    ax = fig.add_subplot(211, projection='3d')
    plot_1 = ax.scatter(xs=X, ys=Y, zs=Z, c=color_variable_1)
    plt.xlabel('x-position')
    plt.ylabel('y-position')
    cbar_1 = fig.colorbar(plot_1)
    ax.text(X_max / 2, 0, Z_max * 1.2, 'membrane')
    ax.text(X_max / 2, Y_max, Z_max * 1.2, 'current collector')
    ax.text(-0.2 * X_max, Y_max / 2, Z_max * 1.2, 'flow inlet')
    ax.text(1.3 * X_max, Y_max / 2, Z_max * 1.2, 'flow outlet')
    cbar_1.ax.set_ylabel('pore concentration [mol/m3]')

    ax2 = fig.add_subplot(212, projection='3d')
    plot_2 = ax2.scatter(xs=X, ys=Y, zs=Z, c=color_variable_2)
    cbar_2 = fig.colorbar(plot_2)
    cbar_2.ax.set_ylabel('liquid potential [V]')
    ax2.text(X_max / 2, 0, Z_max * 1.2, 'membrane')
    ax2.text(X_max / 2, Y_max, Z_max * 1.2, 'current collector')
    ax2.text(-0.2 * X_max, Y_max / 2, Z_max * 1.2, 'flow inlet')
    ax2.text(1.3 * X_max, Y_max / 2, Z_max * 1.2, 'flow outlet')
    plt.draw()

    return fig

推荐答案

有两种方法可以做到这一点

Two ways you could do this would be

  • 结合使用 set_offsets() set_3d_properties
  • 清除figure 和/或axes 对象并在每次迭代中绘制一个新的scatter
  • Use a combination of set_offsets() and set_3d_properties
  • Clear the figure and/or axes object(s) and plot a new scatter every iteration

使用 set_offsets()set_3d_properties 的示例:

Example using set_offsets() and set_3d_properties:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

x = np.linspace(0, np.pi*2, 25)
y = np.sin(x)
z = np.cos(x)

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

def plot(ax):
    return ax.scatter(x, y, z)

def update(s):
    s.set_offsets(np.stack([x, y], 1))
    s.set_3d_properties(z, 'z')

s = plot(ax)
plt.savefig("./before.png")
y = np.cos(x)
z = np.sin(x)
update(s)
plt.savefig("./after.png")

示例清除和重绘:

def plot(fig, ax):
    ax.scatter(x, y, z)

plot(fig, ax)
plt.savefig("./before.png")
y = np.cos(x)
z = np.sin(x)
plt.cla()
plot(fig, ax)
plt.savefig("./after.png")

或者,如果您想在同一个散点图中累积每次迭代的数据,您可以将新数据点附加到 xy z 对象并使用上述方法之一.

Or, if you want to accumulate the data from every iteration in the same scatter plot, you can just append the new data points to the x, y, and z objects and use one of the above methods.

累积示例:

def plot(ax):
    return ax.scatter(x, y, z)

def update(s):
    s.set_offsets(np.stack([x, y], 1))
    s.set_3d_properties(z, 'z')

s = plot(ax)
plt.savefig("./before.png")
x = np.vstack([x,x])
y = np.vstack([y, np.cos(x)])
z = np.vstack([z, np.sin(x)])
update(s)
plt.savefig("./after.png")

我推荐 set_offsets()set_3d_properties() 的组合.请参见此答案有关确定 figure axes 对象的范围的更多信息.

I would recommend the combination of set_offsets() and set_3d_properties(). See this answer for more about scoping the figure and axes objects.

这篇关于在收敛迭代期间更新 3d python 图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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