2017-04-08 157 views
1

我用一個直方圖的四個子圖分別根據隨機正態,伽馬,指數和均勻分佈製作了一個圖。我用matplotlib和Jupyter筆記本做了它。這是一個通過ipywidgets lib的交互式圖形。特別是,有四個滑動條控制每個直方圖上的樣本大小並相應地更新它們。但是,更新直方圖時,它令人生厭地閃爍。有什麼辦法可以避免這種情況?謝謝。ipywidgets:使用交互時避免閃爍

現在的代碼要在jupyter筆記本運行:

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
%matplotlib notebook 
from ipywidgets import * 

n = 1000 
x1 = np.random.normal(-2.5, 1, n) 
x2 = np.random.gamma(2, 1.5, n) 
x3 = np.random.exponential(2, n)+7 
x4 = np.random.uniform(14,20, n) 
x = [x1, x2, x3, x4] 

fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(10,7)) 
axs = [ax1,ax2,ax3,ax4] 

titles = ['x1\nNormal', 'x2\nGamma', 'x3\nExponential', 'x4\nUniform'] 
subplots_axes = [[-7,2,0,250], [0,4.5,0,250], [7,25,0,250], [14,20,0,250]] 

bins = [np.arange(-6, 6, 0.5), 
np.arange(0, 10, 0.5), 
np.arange(7, 17, 0.5), 
np.arange(14, 24, 0.5)] 

fig.subplots_adjust(hspace=0.5) 

def plt_dist(s, sample): 
    axs[s].hist(x[s][:sample], bins=bins[s], linewidth=0, color='#1F77B4') 
    axs[s].axis(subplots_axes[s]) 
    axs[s].set_title('{}'.format(titles[s])) 
    axs[s].set_ylabel('Frequency') 
    axs[s].set_xlabel('Value') 
    axs[s].annotate('n = {}'.format(sample), xycoords='axes fraction', xy = [0.8,0.9]) 
    display(fig) 

for s in range(0,4): 
    sld_bar = interact(plt_dist, s = fixed(s), sample = widgets.IntSlider(min=100,max=1000+45,step=1,value=100)) 

回答

1

這不是真的清楚什麼display(fig)會做它的需要或什麼。

對於我來說,去除線,並在plt_hist功能的開始,而不是清除軸(axs[s].clear())的作品只是罰款和「閃爍」是不存在了。

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
%matplotlib notebook 
from ipywidgets import * 

n = 1000 
x1 = np.random.normal(-2.5, 1, n) 
x2 = np.random.gamma(2, 1.5, n) 
x3 = np.random.exponential(2, n)+7 
x4 = np.random.uniform(14,20, n) 
x = [x1, x2, x3, x4] 

fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(10,7)) 
axs = [ax1,ax2,ax3,ax4] 

titles = ['x1\nNormal', 'x2\nGamma', 'x3\nExponential', 'x4\nUniform'] 
subplots_axes = [[-7,2,0,250], [0,4.5,0,250], [7,25,0,250], [14,20,0,250]] 

bins = [np.arange(-6, 6, 0.5), 
np.arange(0, 10, 0.5), 
np.arange(7, 17, 0.5), 
np.arange(14, 24, 0.5)] 

fig.subplots_adjust(hspace=0.5) 

def plt_dist(s, sample): 
    axs[s].clear() # <-- clear axes 
    axs[s].hist(x[s][:sample], bins=bins[s], linewidth=0, color='#1F77B4') 
    axs[s].axis(subplots_axes[s]) 
    axs[s].set_title('{}'.format(titles[s])) 
    axs[s].set_ylabel('Frequency') 
    axs[s].set_xlabel('Value') 
    axs[s].annotate('n = {}'.format(sample), xycoords='axes fraction', xy = [0.8,0.9]) 
    #display(fig) <--- delete this 

for s in range(0,4): 
    sld_bar = interact(plt_dist, s = fixed(s), 
       sample = widgets.IntSlider(min=100,max=1000+45,step=1,value=100)) 
+0

我必須使用'display(fig)',因爲我想用四個子圖使用for循環更新一個圖,就像在[這裏](http://stackoverflow.com/questions/21360361/how -to-動態更新-A-情節在-A - 環 - 在-IPython的筆記本中之單細胞)。否則,該圖不顯示。我曾嘗試過使用'plt.cla()',但它不起作用。 –

+0

那麼,你可以從我的答案中運行腳本嗎?根據是否有效,我們可以找到for-loops的解決方案。 – ImportanceOfBeingErnest

+0

是的,我可以。該解決方案沒有問題。 –