2017-04-08 3 views
1

Ich habe eine Figur mit vier Untergraphen eines Histogramms auf der Grundlage von zufälligen Normal-, Gamma, Exponential- und Gleichverteilung erstellt. Ich habe es mit Matplotlib und Jupyter Notebook gemacht. Es ist eine interaktive Figur über ipywidgets lib. Insbesondere gibt es vier Schieberegler, die die Probengröße in jedem Histogramm steuern und entsprechend aktualisieren. Beim Aktualisieren der Histogramme flackert es jedoch ärgerlich. Gibt es eine Möglichkeit, dies zu vermeiden? Danke.ipywidgets: flackern bei der Interaktion zu vermeiden

Jetzt ist der Code auf einem jupyter Notebook ausgeführt werden soll:

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

Antwort

1

Es ist nicht wirklich klar, was display(fig) tun würde, oder was es für nötig ist.

Für mich funktioniert das Entfernen der Linie und das Löschen der Achsen (axs[s].clear()) am Anfang der plt_hist Funktion gut und das "Flackern" ist nicht mehr da.

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

Ich habe verwenden 'Display (Bild)', weil ich eine Figur mit vier Handlungsstränge mit einer for-Schleife aktualisieren möchten, wie in [hier] (http://stackoverflow.com/questions/21360361/how -update-in-a-loop-in-ipython-notebook-in-one-cell). Ansonsten zeigt die Figur nicht. Ich habe versucht, 'plt.cla()' vorher zu benutzen, aber es funktioniert nicht. –

+0

Also, können Sie das Skript aus meiner Antwort ausführen oder nicht? Je nachdem, ob das funktioniert oder nicht, können wir eine Lösung für die For-Schleifen finden. – ImportanceOfBeingErnest

+0

Ja, ich kann. Kein Problem mit dieser Lösung. –

Verwandte Themen