Ipython नोटबुक में एक लूप में प्लॉट को गतिशील रूप से कैसे अपडेट करें (एक सेल के भीतर)


93

पर्यावरण: पायथन 2.7, मैटलोट्लिब 1.3, आईपीथॉन नोटबुक 1.1, लिनक्स, क्रोम। कोड एक एकल इनपुट सेल में है, का उपयोग करके--pylab=inline

मैं एक स्ट्रीम का उपभोग करने और गतिशील रूप से हर 5 सेकंड में एक प्लॉट को अपडेट करने के लिए IPython नोटबुक और पांडा का उपयोग करना चाहता हूं।

जब मैं सिर्फ टेक्स्ट फॉर्मेट में डेटा प्रिंट करने के लिए प्रिंट स्टेटमेंट का उपयोग करता हूं, तो यह पूरी तरह से ठीक काम करता है: आउटपुट सेल सिर्फ डेटा प्रिंट करता है और नई पंक्तियों को जोड़ता है। लेकिन जब मैं डेटा को प्लॉट करने की कोशिश करता हूं (और फिर इसे लूप में अपडेट करता हूं), तो प्लॉट कभी आउटपुट सेल में दिखाई नहीं देता है। लेकिन अगर मैं लूप को हटा देता हूं, तो बस एक बार प्लॉट करें। यह बढ़िया काम करता है।

फिर मैंने कुछ सरल परीक्षण किया:

i = pd.date_range('2013-1-1',periods=100,freq='s')
while True:
    plot(pd.Series(data=np.random.randn(100), index=i))
    #pd.Series(data=np.random.randn(100), index=i).plot() also tried this one
    time.sleep(5)

आउटपुट कुछ भी नहीं दिखाएगा जब तक कि मैं मैन्युअल रूप से प्रक्रिया को बाधित नहीं करता (ctrl + m + i)। और मैं इसे बाधित करने के बाद, प्लॉट को कई ओवरलैप की गई लाइनों के रूप में सही ढंग से दिखाता है। लेकिन जो मैं वास्तव में चाहता हूं वह एक ऐसा प्लॉट है जो हर 5 सेकंड में अपडेट हो जाता है और अपडेट हो जाता है (या जब भी plot()फ़ंक्शन को कॉल किया जाता है, ठीक उसी तरह जैसे कि मैंने ऊपर बताए गए प्रिंट स्टेटमेंट आउटपुट क्या कहते हैं, जो अच्छी तरह से काम करता है)। सेल पूरी तरह से हो जाने के बाद केवल अंतिम चार्ट दिखाना केवल वही नहीं है जो मैं चाहता हूं।

मैंने प्रत्येक के बाद स्पष्ट रूप से ड्रा () फ़ंक्शन को जोड़ने की कोशिश की plot(), आदि उनमें से कोई भी काम नहीं करता है। आश्चर्य है कि IPython नोटबुक में एक सेल के भीतर / जबकि लूप द्वारा प्लॉट को गतिशील रूप से कैसे अपडेट किया जाए।

जवाबों:


122

IPython.displayमॉड्यूल का उपयोग करें:

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

4
यह सुगम विकल्प नहीं है, प्लॉट को सेल से ऊपर और नीचे जाने के साथ खरोंच से बनाया गया है
denfromufa

3
जोड़ा जा रहा है clear_output(wait=True)हल करती है इस समस्या। नीचे देखें वाबु का जवाब
आह्विलिया

3
आप इन दिनों में बेहतर कर सकते हैं %matplotlib nbaggजिसके साथ आपको खेलने के लिए एक लाइव आंकड़ा मिलता है।
ताकसवेल

@tcaswell मैंने एक नया प्रश्न जोड़ा है जिसमें पूछा गया है कि nbaggइसे प्राप्त करने के लिए कोई कैसे उपयोग करता है। (यदि आप इसका जवाब देने में रुचि रखते हैं तो पिंग करना।) stackoverflow.com/questions/34486642/…
नथानिएल

3
यह काम करता है लेकिन सेल में मुद्रित उपायों की तरह कुछ भी नष्ट कर देता है। वहाँ वास्तव में सिर्फ भूखंड को अद्यतन करने और बाकी सब जगह रखने का एक तरीका है?
KIC

31

आप आगे जोड़कर इस सुधार कर सकते हैं wait=Trueकरने के लिए clear_output:

display.clear_output(wait=True)
display.display(pl.gcf())

1
+1। यह बहुत महत्वपूर्ण है। मुझे लगता है कि HYRY के जवाब को इस जानकारी के साथ अपडेट किया जाना चाहिए।
अहिलिया 18

5
यह अच्छा है, लेकिन साथ ही प्रिंट आउटपुट को साफ़ करने का कष्टप्रद पक्ष प्रभाव है।
पीटर

31

HYRY के जवाब पर सुधार की एक जोड़ी :

  • displayइससे पहले clear_outputकि आप सेल को बाधित होने पर दो के बजाय एक प्लॉट के साथ कॉल करें ।
  • KeyboardInterruptसेल आउटपुट ट्रेसबैक के साथ अटे पड़े नहीं है, ताकि पकड़ ।
import matplotlib.pylab as plt
import pandas as pd
import numpy as np
import time
from IPython import display
%matplotlib inline

i = pd.date_range('2013-1-1',periods=100,freq='s')

while True:
    try:
        plt.plot(pd.Series(data=np.random.randn(100), index=i))
        display.display(plt.gcf())
        display.clear_output(wait=True)
        time.sleep(1)
    except KeyboardInterrupt:
        break

7
वास्तव में, display.display(gcf()) display.clear_output(wait=True)
उससे

धन्यवाद, @csta इसे जोड़ा।
टॉम फिलिप्स

@ herrlich10 displayको पहले क्यों बुलाया जाना चाहिए clear_output? क्या आपको पहले आउटपुट को साफ़ नहीं करना चाहिए और फिर नए डेटा को प्रदर्शित करना चाहिए, बजाय इसके कि यह दूसरे तरीके से करे?
जैकब अर्नोल्ड

1
मुझे अभी भी ग्राफ़ अपडेट के साथ एक स्क्रीन झिलमिलाहट मिल रही है, हालांकि यह हर समय नहीं है। क्या इसमें वर्कअराउंड है?
MasayoMusic

2

फ़ंक्शन के बाद show()या जोड़ने का प्रयास करें । ये वर्तमान आंकड़े को अपडेट करने के लिए मजबूर करेंगे (gcf () वर्तमान आकृति के लिए एक संदर्भ देता है)।gcf().show()plot()


2
धन्यवाद। gcf ()। show () भी काम करता है। उसी अंजीर पर सामान दिखाने के लिए HYRY द्वारा सुझाए गए clear_output () को जोड़ने की आवश्यकता है
user3236895

क्या यह "display.display (pl.gcf ())" के अलावा है?
MasayoMusic

2

यहां पोस्ट किए गए अन्य समाधानों में लेबल जोड़ना हर लूप में नए लेबल जोड़ते रहेंगे। उस से निपटने के लिए, प्लॉट का उपयोग करके साफ़ करेंclf

for t in range(100)
   if t % refresh_rate == 0:

     plt.clf()
     plt.plot(history['val_loss'], 'r-', lw=2, label='val')
     plt.plot(history['training_loss'], 'b-', lw=1, label='training')
     plt.legend()
     display.clear_output(wait=True)
     display.display(plt.gcf())


4
धन्यवाद plt.clf()काम करता है। हालांकि अद्यतन से फ़्लिकर से छुटकारा पाने के लिए वैसे भी क्या है?
MasayoMusic

0

आप इसे इस तरह से कर सकते हैं। यह 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.