3d 交互式图形不会更新 [英] 3d interactive graph won't update

查看:32
本文介绍了3d 交互式图形不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用此代码创建了一个交互式绘图 (2d),并且可以正常工作.

将 numpy 导入为 np导入 matplotlib.pyplot 作为 plt从 matplotlib.widgets 导入滑块、按钮、单选按钮图, ax = plt.subplots()plt.subplots_adjust(左=0.25,底部=0.25)t = np.arange(0.0, 1.0, 0.001)0 = 5f0 = 3s = a0*np.sin(2*np.pi*f0*t)l, = plt.plot(t, s, lw=2, color='red')plt.axis([0, 1, -10, 10])axcolor = 'lightgoldenrodyellow'axfreq = plt.axes([0.25, 0.1, 0.65, 0.03],axisbg=axcolor)axamp = plt.axes([0.25, 0.15, 0.65, 0.03],axisbg=axcolor)sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)定义更新(val):amp = samp.val频率 = 频率.vall.set_ydata(amp*np.sin(2*np.pi*freq*t))fig.canvas.draw_idle()sfreq.on_changed(更新)samp.on_changed(更新)resetax = plt.axes([0.8, 0.025, 0.1, 0.04])按钮 = 按钮(重置,'重置',颜色=axcolor,hovercolor='0.975')定义重置(事件):sfreq.reset()samp.reset()button.on_clicked(重置)rax = plt.axes([0.025, 0.5, 0.15, 0.15],axisbg=axcolor)radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0)def colorfunc(标签):l.set_color(标签)fig.canvas.draw_idle()radio.on_clicked(colorfunc)plt.show()

然后我尝试修改它以通过简单地将轴更改为轴 3d 来创建交互式 3d 绘图.我添加了如下所示的导入语句,并将fig"和ax"的定义替换为如下所示的定义,成为 3d.

from mpl_toolkits.mplot3d 导入 Axes3Dfig = plt.figure()ax = fig.add_subplot(111, 投影='3d')

情节不再更新,我不知道为什么.函数 fig.canvas.draw_idle() 似乎不适用于 3d 图形,但我没有其他更新图形的方法.

任何帮助将不胜感激,

谢谢!

解决方案

通过查看更新的颜色,您可以看到函数 fig.canvas.draw_idle() 确实存在并且按预期工作.

问题在于 set_ydata 函数,它在 3d 空间中的工作方式不同.假设您希望 y 坐标更新并且 z 坐标保持不变,set_data 将被赋予常量值,而附加属性 set_3d_properties() 需要设置来控制 y 坐标.>

这是工作示例代码:

将 numpy 导入为 np导入 matplotlib.pyplot 作为 plt从 mpl_toolkits.mplot3d 导入 Axes3D从 matplotlib.widgets 导入滑块、按钮、单选按钮fig = plt.figure()ax = fig.add_subplot(111, 投影=3d")plt.subplots_adjust(左=0.25,底部=0.25)t = np.arange(0.0, 1.0, 0.001)### 创建常量 z 坐标z = np.zeros_like(t) # <------------ 这里0 = 5f0 = 3s = a0*np.sin(2*np.pi*f0*t)l, = plt.plot(t, s, lw=2, color='red')plt.axis([0, 1, -10, 10])axfreq = plt.axes([0.25, 0.1, 0.65, 0.03],axisbg="w")axamp = plt.axes([0.25, 0.15, 0.65, 0.03],axisbg="w")sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)定义更新(val):amp = samp.val频率 = 频率.val#设置常量z坐标l.set_data(t, z) # <------------这里# 将值设置为 y 坐标l.set_3d_properties(amp*np.sin(2*np.pi*freq*t), zdir="y") #<------------这里fig.canvas.draw_idle()sfreq.on_changed(更新)samp.on_changed(更新)resetax = plt.axes([0.8, 0.025, 0.1, 0.04])按钮 = 按钮(重置,'重置',颜色=axcolor,hovercolor='0.975')定义重置(事件):sfreq.reset()samp.reset()button.on_clicked(重置)rax = plt.axes([0.025, 0.5, 0.15, 0.15],axisbg=axcolor)radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0)def colorfunc(标签):l.set_color(标签)fig.canvas.draw_idle()radio.on_clicked(colorfunc)plt.show()

I was using this code to create an interactive plot (2d), and it works.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons

fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t, s, lw=2, color='red')
plt.axis([0, 1, -10, 10])

axcolor = 'lightgoldenrodyellow'
axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
axamp = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)

sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)


def update(val):
    amp = samp.val
    freq = sfreq.val
    l.set_ydata(amp*np.sin(2*np.pi*freq*t))
    fig.canvas.draw_idle()
sfreq.on_changed(update)
samp.on_changed(update)

resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')


def reset(event):
    sfreq.reset()
    samp.reset()
button.on_clicked(reset)

rax = plt.axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor)
radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0)


def colorfunc(label):
    l.set_color(label)
    fig.canvas.draw_idle()
radio.on_clicked(colorfunc)

plt.show()

I then tried to modify it to create an interactive 3d plot by simply changing the axes to axes3d. I added the import statement shown below and replaced the definition of "fig" and "ax" with those shown below to become 3d.

from mpl_toolkits.mplot3d import Axes3D

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

The plot no longer updates, and I can't figure out why. It seems that the function fig.canvas.draw_idle() doesn't work on 3d graphs, but I don't have another way of updating the graph.

Any help would be appreciated,

Thanks!

解决方案

You can see that the function fig.canvas.draw_idle() does exist and works as expected by looking at the colors which become updated.

The problem lies in the set_ydata function, which works differently in 3d space. Assuming that you want the y coordinate to update and the z-coordinate to be constant, set_data will be given the constant values, while an additional property set_3d_properties() needs to be set to control the y-coordinate.

Here is the working example code:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.widgets import Slider, Button, RadioButtons

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
plt.subplots_adjust(left=0.25, bottom=0.25)
t = np.arange(0.0, 1.0, 0.001)
### create constant z-coordinate
z = np.zeros_like(t)    #               <------------ here
a0 = 5
f0 = 3
s = a0*np.sin(2*np.pi*f0*t)
l, = plt.plot(t, s, lw=2, color='red')
plt.axis([0, 1, -10, 10])

axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg="w")
axamp = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg="w")

sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0)
samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0)


def update(val):
    amp = samp.val
    freq = sfreq.val
    #set constant z coordinate
    l.set_data(t, z)  #               <------------ here
    # set values to y-coordinate
    l.set_3d_properties(amp*np.sin(2*np.pi*freq*t), zdir="y") #<------------ here
    fig.canvas.draw_idle()

sfreq.on_changed(update)
samp.on_changed(update)

resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')


def reset(event):
    sfreq.reset()
    samp.reset()
button.on_clicked(reset)

rax = plt.axes([0.025, 0.5, 0.15, 0.15], axisbg=axcolor)
radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0)


def colorfunc(label):
    l.set_color(label)
    fig.canvas.draw_idle()
radio.on_clicked(colorfunc)

plt.show()

这篇关于3d 交互式图形不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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