3d 交互式图形不会更新 [英] 3d interactive graph won't update
问题描述
我使用此代码创建了一个交互式绘图 (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屋!