【问题标题】:Clear MatPlotLib figure in Jupyter Python notebook在 Jupyter Python 笔记本中清除 MatPlotLib 图
【发布时间】:2017-08-17 07:17:34
【问题描述】:

我希望 MatPlotLib 中的 3D 散点图在 Jupyter Python 笔记本中以交互方式旋转。出于这个原因,我从ipywidgets 集成了一个滑块来更新视角。下面的测试代码显示了我想要实现的目标。问题是在前一个数字下方添加了一个新数字,而不是清除当前数字。我尝试了plt.close(fig)plt.cla()plt.clf(),但没有成功。 (进一步我意识到重新创建图形和轴有开销,但这是我目前关注的较小部分......)

这是(测试)代码:

# init
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import ipywidgets as widgets
from IPython.display import display

# generate test data
x = np.random.rand(100)
y = np.random.rand(100)
z = np.random.rand(100)

# prepare plot
def draw_plot(angle1 = 20, angle2 = 40):
    # create figure
    fig = plt.figure(figsize=(15,10))
    ax = fig.add_subplot(111, projection='3d')
    ax.set_xlabel('X axis')
    ax.set_ylabel('Y axis')
    ax.set_zlabel('Z axis')
    ax.scatter(x, y, z)

    # set view angle
    ax.view_init(angle1, angle2)

    # show plot
    plt.show()

# prepare widgets
angle1_slider = widgets.IntSlider(20, min = 0, max = 60)
angle1_label = widgets.Label(value = 'Angle 1 value is: ' + str(angle1_slider.value))
display(angle1_slider, angle1_label)

# handle angle 1 update
def update_angle1(value):
    draw_plot(angle1 = value['new'])
    angle1_label.value = 'Angle 1 value is: ' + str(value.new)

angle1_slider.observe(update_angle1, names = 'value')

# draw initial plot
draw_plot()

任何建议将不胜感激!

【问题讨论】:

    标签: python matplotlib jupyter-notebook ipywidgets


    【解决方案1】:

    您所说的开销是问题的根源。或者换句话说:如果在每次调用该函数时,都会创建一个新图形,那么您最终会得到很多图形,这是否令人惊讶?

    这个想法当然是画一个单一的图形。为了以后能够更新图形,需要%matplotlib notebook 后端。

    更改滑块时调用的函数将只需要更新视角并重新绘制画布。

    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    import ipywidgets as widgets
    from IPython.display import display
    %matplotlib notebook
    
    # generate test data
    x = np.random.rand(100)
    y = np.random.rand(100)
    z = np.random.rand(100)
    
    
    fig = plt.figure(figsize=(6,6))
    ax = fig.add_subplot(111, projection='3d')
    ax.set_xlabel('X axis')
    ax.set_ylabel('Y axis')
    ax.set_zlabel('Z axis')
    ax.scatter(x, y, z)
    ax.view_init(20, 40)
    # show plot
    plt.show()
    
    def update_plot(angle1 = 20, angle2 = 40):
        # set view angle
        ax.view_init(angle1, angle2)
        fig.canvas.draw_idle()
    
    # prepare widgets
    angle1_slider = widgets.IntSlider(20, min = 0, max = 60)
    angle1_label = widgets.Label(value = 'Angle 1 value is: ' + str(angle1_slider.value))
    display(angle1_slider, angle1_label)
    
    # handle angle 1 update
    def update_angle1(value):
        update_plot(angle1 = value['new'])
        angle1_label.value = 'Angle 1 value is: ' + str(value.new)
    
    angle1_slider.observe(update_angle1, names = 'value')
    

    这就是它的样子:

    【讨论】:

    • 太棒了!我不知道fig.canvas.draw_idle() 确实解决了这个问题。更好的是,我一直使用%matplotlib inline,但%matplotlib notebook 也非常有用!谢谢!
    猜你喜欢
    • 2021-03-22
    • 2017-05-15
    • 2018-10-10
    • 2017-05-22
    • 2017-05-15
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多