2017-03-24 11 views
1

MatPlotLibの3D散布図をJupyter Pythonノートブックでインタラクティブに回転させたい。そのため、私はipywidgetsのスライダを統合してビューアングルを更新しました。以下のテストコードは私が達成しようとしていることを示しています。問題は、現在の図が消去されず、前の図の下に新しい図が追加されることです。私はplt.close(fig)plt.cla()plt.clf()を成功裏に試しました。Jupyter PythonノートブックでMatPlotLibをクリア

# 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() 

任意の提案をします:ここで

は(テスト)コードである(さらに私は...そこのFigureとAxesを再作成して、オーバーヘッドですが、それは私の現在の懸念の小さい部分であることを認識します)ありがとう!

答えて

4

オーバーヘッドと呼ばれるものが問題の原因です。言い換えれば、関数の呼び出しごとに新しい図形が作成された場合、多くの図形で終わるのは驚くべきことですか?

もちろん、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') 

これは、次のようになります方法です:

enter image description here

+0

素晴らしいです!本当に問題を解決した 'fig.canvas.draw_idle()'は知らなかった。さらに、私はいつも '%matplotlib inline'を使っていましたが、'%matplotlib notebook 'はとても便利です!ありがとう! – Pieter

関連する問題