वर्तमान में Jupyter / iPython में प्लॉट को गतिशील रूप से अपडेट करने का सही तरीका क्या है?


93

IPython नोटबुक में एक लूप में प्लॉट को गतिशील रूप से कैसे अपडेट किया जाए इसके जवाब में (एक सेल के भीतर) , एक उदाहरण दिया गया है कि Python लूप के भीतर Jupyter नोटबुक के अंदर प्लॉट को गतिशील रूप से कैसे अपडेट किया जाए। हालांकि, यह प्रत्येक पुनरावृत्ति पर प्लॉट को नष्ट करने और फिर से बनाने के द्वारा काम करता है, और थ्रेड्स में से एक में टिप्पणी करता है कि नए-ईश %matplotlib nbaggजादू का उपयोग करके इस स्थिति में सुधार किया जा सकता है, जो नोटबुक में एम्बेडेड इंटरएक्टिव आंकड़ा प्रदान करता है, बल्कि स्थिर छवि की तुलना में।

हालाँकि, यह अद्भुत नई nbaggसुविधा पूरी तरह से अबाधित है, जहाँ तक मैं बता सकता हूँ, और मैं इसका एक उदाहरण नहीं पा रहा हूँ कि कैसे इसका उपयोग गतिशील रूप से एक भूखंड को अपडेट करने के लिए किया जाए। इस प्रकार मेरा सवाल यह है कि एक जुपिटर / पायथन नोटबुक में मौजूदा प्लाट को कुशलता से कैसे अपडेट किया जा सकता है? चूंकि मैटलपोटलिब में गतिशील रूप से अपडेट किए गए प्लॉट सामान्य रूप से एक मुश्किल मुद्दा है, इसलिए एक साधारण कामकाजी उदाहरण एक बहुत बड़ी मदद होगी। विषय पर किसी भी प्रलेखन के लिए एक सूचक भी बहुत उपयोगी होगा।

यह स्पष्ट करने के लिए कि मैं क्या पूछ रहा हूं: जो मैं करना चाहता हूं वह कुछ पुनरावृत्तियों के लिए कुछ सिमुलेशन कोड चलाने के लिए है, फिर इसकी वर्तमान स्थिति का एक भूखंड ड्रा करें, फिर इसे कुछ और पुनरावृत्तियों के लिए चलाएं, फिर प्रतिबिंबित करने के लिए भूखंड को अपडेट करें वर्तमान स्थिति, और इसी तरह। इसलिए विचार यह है कि एक भूखंड को आकर्षित किया जाए और फिर, उपयोगकर्ता से किसी भी बातचीत के बिना, पूरी बात को नष्ट किए और फिर से बनाए बिना भूखंड में डेटा को अपडेट करें।

यहां ऊपर दिए गए लिंक किए गए प्रश्न के उत्तर से कुछ थोड़ा संशोधित कोड है, जो हर बार पूरे आंकड़े को फिर से ड्राइंग करके इसे प्राप्त करता है। मैं एक ही परिणाम प्राप्त करना चाहता हूं, लेकिन अधिक कुशलता से उपयोग कर रहा हूं 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)

जवाबों:


62

यहां एक उदाहरण दिया गया है जो एक प्लॉट को लूप में अपडेट करता है। यह आंकड़े में डेटा को अपडेट करता है और हर बार पूरे आंकड़े को फिर से नहीं बनाता है। यह ब्लॉक निष्पादन करता है, हालांकि यदि आप सिमुलेशन के एक सीमित सेट को चलाने में रुचि रखते हैं और परिणाम कहीं बचा रहे हैं, तो यह आपके लिए समस्या नहीं हो सकती है।

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

मैंने इसे यहाँ nbviewer पर रखा है।

वहाँ एक IPython विजेट संस्करण है nbaggकि वर्तमान में Matplotlib भंडार में प्रगति पर एक काम है । जब यह उपलब्ध है, तो यह संभवतः उपयोग करने का सबसे अच्छा तरीका होगा nbagg

संपादित करें: कई प्लॉट दिखाने के लिए अपडेट किया गया


1
महान, यह अच्छी तरह से काम करने लगता है। यह चल रहा है, जबकि अन्तरक्रियाशीलता की कमी मेरे लिए एक बड़ी समस्या नहीं है। एक छोटी सी अजीब बात है: अगर मैं while True:एक लूप के लिए बदल जाता हूं , जब लूप समाप्त होता है तो मुझे एक इंटरएक्टिव नैबग एक के बजाय अंतिम भूखंड की दो स्थिर छवियां मिलती हैं। किसी भी विचार क्यों है?
नथानिएल

मैंने कुछ समय के लिए लूप में बदलाव किया और इसे tmpnb.org पर आज़माया, और मैं दूसरी छवि या अन्तरक्रियाशीलता का नुकसान नहीं देख रहा हूँ। अंधेरे में गोली मार दी, लेकिन आप फ़ंक्शन में लूप होने के बजाय कॉल को फ़ंक्शन के चारों ओर ले जाने का प्रयास कर सकते हैं। f में सीमा के लिए (10): pltsin (कुल्हाड़ी) time.sleep (1)
न्यूमैटिक्स

3
@ वायवीय दुर्भाग्य से रेटिना डिस्प्ले पर Matplotlib 2.0 के साथ कुछ समस्याएं हैं: लूप भूखंडों में आमतौर पर दो बार छोटे होते हैं।
अलेक्जेंडर रोडिन

1
ऐसा लगता है कि आंकड़े को खुद को सही ढंग से आकार देने का समय नहीं दिया गया है। इसलिए मेरे पास एक बेहतर अनुभव था जब एक को डालकर plt.show()अगले सेल के लिए फॉर-लूप को आगे बढ़ाया।
ImportanceOfBeingErnest

2
सुनिश्चित करें कि आपके पास अपने प्लॉट के रूप में एक ही ज्यूपिटर नोटबुक सेल में% matplotlib नोटबुक है - मैंने आज 2 घंटे से अधिक का समय बिताया क्योंकि इस समस्या का निवारण करने के लिए मेरे पास पहले सेल में% matplotlib नोटबुक था
आयातकों के

12

मैं ज्यूपिटर-लैब का उपयोग कर रहा हूं और यह मेरे लिए काम करता है (इसे आपके मामले में अनुकूलित करें):

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

फिर एक लूप में आप एक शब्दकोश को पॉप्युलेट करते हैं और आप इसे पास करते हैं 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)

सुनिश्चित करें कि आपके पास प्लॉट के नीचे कुछ कोशिकाएं हैं, अन्यथा हर बार प्लॉट के फिर से खोले जाने पर दृश्य स्नैप हो जाता है।


1
यह मौजूदा प्लॉट
न्यूमैटिक्स

2
सही बात। मुझे जुपिटर-लैब में एक डायनेमिक प्लॉट होने का एक बेहतर तरीका नहीं मिला है।
जिओफिल

1
क्या पुनरावृत्तियों के बीच प्रतीक्षा करने का कोई तरीका है? केवल 'प्रतीक्षा = सत्य' होने के बजाय
अहमद मौसा

1
हर बार प्लॉट को फिर से तैयार किया जाता है, ग्राफ़ फ़्लिकर करता है। क्या इस समस्या के समाधान का कोई तरीका है? मेरे पास प्लॉट के नीचे कुछ खाली सेल हैं, लेकिन वह मदद नहीं करता है।
मासायोमासिक


0

मैंने @Ziofil उत्तर को अनुकूलित कर लिया है और सूची के रूप में x, y को स्वीकार करने के लिए इसे संशोधित किया है और एक ही प्लॉट पर एक स्कैटर प्लॉट और एक रैखिक प्रवृत्ति का उत्पादन किया है।

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

आपको बस live_plot(x, y)एक लूप के अंदर कॉल करने की आवश्यकता है । यहाँ है कि यह कैसा दिखता है: यहाँ छवि विवरण दर्ज करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.