Jupyter / iPython'da grafikleri dinamik olarak güncellemenin şu anda doğru yolu nedir?


93

Cevapları ise dinamik olarak (bir hücrenin içinde) ipython defterindeki bir döngü içinde bir arsa güncellemek için nasıl bir örnek dinamik bir Python döngü içinde Jupyter dizüstü içinde bir arsa güncellemek için nasıl verilir. Bununla birlikte, bu, her yinelemede arsayı yok ederek ve yeniden oluşturarak çalışır ve iş parçacıklarından birindeki yorum, bu durumun %matplotlib nbaggnot defterine gömülü etkileşimli bir figür sağlayan new-ish büyüsü kullanılarak iyileştirilebileceğini belirtir. statik bir görüntüden daha fazla.

Bununla birlikte, bu harika yeni nbaggözellik, söyleyebildiğim kadarıyla tamamen belgelenmemiş gibi görünüyor ve bir planı dinamik olarak güncellemek için nasıl kullanılacağına dair bir örnek bulamıyorum. Dolayısıyla sorum şu, bir Jupyter / Python not defterinde mevcut bir arsa nbagg arka ucunu kullanarak verimli bir şekilde nasıl güncellenebilir? Matplotlib'deki grafikleri dinamik olarak güncellemek genel olarak zor bir konu olduğu için, basit bir çalışma örneği çok yardımcı olacaktır. Konuyla ilgili herhangi bir dokümantasyona bir işaretçi de son derece yardımcı olacaktır.

Ne istediğimi açıklığa kavuşturmak için: Yapmak istediğim, birkaç yineleme için bir simülasyon kodu çalıştırmak, ardından mevcut durumunun bir grafiğini çizmek, ardından birkaç yineleme için çalıştırmak ve ardından grafiği yansıtacak şekilde güncellemek mevcut durum, vb. Yani fikir, bir olay örgüsü çizmek ve ardından kullanıcının herhangi bir etkileşimi olmadan, her şeyi yok etmeden ve yeniden oluşturmadan arsadaki verileri güncellemektir.

İşte yukarıdaki bağlantılı soruya verilen yanıttan biraz değiştirilmiş bir kod, bunu her seferinde tüm şekli yeniden çizerek başarır. Aynı sonucu elde etmek ama daha verimli kullanmak istiyorum nbagg.

%matplotlib inline
import time
import pylab as pl
from IPython import display
for i in range(10):
    pl.clf()
    pl.plot(pl.randn(100))
    display.display(pl.gcf())
    display.clear_output(wait=True)
    time.sleep(1.0)

Yanıtlar:


62

İşte bir döngüdeki bir grafiği güncelleyen bir örnek. Şekildeki verileri günceller ve her seferinde tüm şekli yeniden çizmez. Yürütmeyi engelliyor, ancak sınırlı bir simülasyon seti çalıştırmak ve sonuçları bir yere kaydetmekle ilgileniyorsanız, sizin için bir sorun olmayabilir.

%matplotlib notebook

import numpy as np
import matplotlib.pyplot as plt
import time

def pltsin(ax, colors=['b']):
    x = np.linspace(0,1,100)
    if ax.lines:
        for line in ax.lines:
            line.set_xdata(x)
            y = np.random.random(size=(100,1))
            line.set_ydata(y)
    else:
        for color in colors:
            y = np.random.random(size=(100,1))
            ax.plot(x, y, color)
    fig.canvas.draw()

fig,ax = plt.subplots(1,1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xlim(0,1)
ax.set_ylim(0,1)
for f in range(5):
    pltsin(ax, ['b', 'r'])
    time.sleep(1)

Bunu nbviewer'a buraya koydum.

Şu anda Matplotlib deposunda devam etmekte olan bir IPython Widget sürümü varnbagg . Bu mevcut olduğunda, muhtemelen kullanmanın en iyi yolu bu olacaktır nbagg.

DÜZENLEME: birden çok grafik göstermek için güncellendi


1
Harika, güzel çalışıyor gibi görünüyor. Çalışırken etkileşim eksikliği benim için büyük bir sorun değil. Biraz garip bir şey: while True:Bir for döngüsünü değiştirirsem, döngü bittiğinde, etkileşimli bir nbagg yerine son arsanın iki statik görüntüsünü elde ederim. Bunun neden olduğu hakkında bir fikriniz var mı?
Nathaniel

Süreyi bir for döngüsü olarak değiştirdim ve tmpnb.org'da denedim, ancak ikinci bir görüntü veya etkileşim kaybı görmüyorum. Karanlıkta çekildi, ancak döngünün işlevde olmasını sağlamak yerine döngüyü işleve çağrı etrafında hareket ettirmeyi deneyebilirsiniz. f aralık (10) için: pltsin (ax) time.sleep (1)
pneumatics

3
@pneumatics Ne yazık ki, Retina ekranındaki Matplotlib 2.0 ile bazı sorunları var: döngüde grafikler genellikle iki kat daha küçük.
Alexander Rodin

1
Görünüşe göre şekle kendisini doğru şekilde yeniden boyutlandırması için zaman verilmemiş. Bu yüzden bir plt.show()sonraki hücreye bir döngü koyarken ve hareket ettirirken çok daha iyi bir deneyim yaşadım .
ImportanceOfBeingErnest

2
Grafiğinizle aynı jupyter not defteri hücresinde% matplotlib not defterine sahip olduğunuzdan emin olun - Bugün bu sorunu gidermek için 2 saatten fazla zaman harcadım çünkü ilk hücrede içe aktarma
ifadeleri

12

Jupyter-lab kullanıyorum ve bu benim için çalışıyor (sizin durumunuza uyarlayın):

from IPython.display import clear_output
from matplotlib import pyplot as plt
import collections
%matplotlib inline

def live_plot(data_dict, figsize=(7,5), title=''):
    clear_output(wait=True)
    plt.figure(figsize=figsize)
    for label,data in data_dict.items():
        plt.plot(data, label=label)
    plt.title(title)
    plt.grid(True)
    plt.xlabel('epoch')
    plt.legend(loc='center left') # the plot evolves to the right
    plt.show();

Sonra bir döngüde bir sözlüğü doldurursunuz ve onu şunlara iletirsiniz live_plot():

data = collections.defaultdict(list)
for i in range(100):
    data['foo'].append(np.random.random())
    data['bar'].append(np.random.random())
    data['baz'].append(np.random.random())
    live_plot(data)

Grafiğin altında birkaç hücreye sahip olduğunuzdan emin olun, aksi takdirde çizim her yeniden çizildiğinde görünüm yerine oturur.


1
bu, mevcut planı güncellemek yerine her seferinde yeni bir olay örgüsü yaratır
pneumatics

2
Doğru. Jupyter laboratuarında dinamik bir olay örgüsüne sahip olmanın daha iyi bir yolunu bulamadım.
Ziofil

1
Yinelemeler arasında ne kadar bekleyeceğini ayarlamanın bir yolu var mı? yerine sadece bir olan 'bekleme = True' den
Ahmed Musa

1
Çizim her yeniden çizildiğinde grafik titriyor. Bu problemi düzeltmenin bir yolu var mı? Planın altında birkaç boş hücrem var ama bu yardımcı olmuyor.
MasayoMusic

@MasayoMusic, buildmedia.readthedocs.org/media/pdf/ipywidgets/latest/… 'de "titreyen ve zıplayan çıktı" konusuna bakın
leo

0

@Ziofil yanıtını uyarladım ve x, y'yi liste olarak kabul edecek ve bir dağılım grafiği artı aynı grafik üzerinde doğrusal bir eğilim çıkacak şekilde değiştirdim.

from IPython.display import clear_output
from matplotlib import pyplot as plt
%matplotlib inline
    
def live_plot(x, y, figsize=(7,5), title=''):
    clear_output(wait=True)
    plt.figure(figsize=figsize)
    plt.xlim(0, training_steps)
    plt.ylim(0, 100)
    x= [float(i) for i in x]
    y= [float(i) for i in y]
    
    if len(x) > 1:
        plt.scatter(x,y, label='axis y', color='k') 
        m, b = np.polyfit(x, y, 1)
        plt.plot(x, [x * m for x in x] + b)

    plt.title(title)
    plt.grid(True)
    plt.xlabel('axis x')
    plt.ylabel('axis y')
    plt.show();

sadece live_plot(x, y)bir döngü içinde aramanız gerekir . şöyle görünüyor: görüntü açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.