इंटरैक्टिव Matplotlib आंकड़े की बचत


119

क्या मैटलपोटलिब फिगर को बचाने का कोई तरीका है ताकि इसे फिर से खोला जा सके और विशिष्ट बातचीत को बहाल किया जा सके? (MATLAB में .fig प्रारूप की तरह?)

मैं खुद को इन इंटरेक्टिव आंकड़े उत्पन्न करने के लिए कई बार एक ही स्क्रिप्ट चला रहा हूं। या मैं एक प्लॉट के विभिन्न पहलुओं को दिखाने के लिए अपने सहयोगियों को कई स्थिर पीएनजी फाइलें भेज रहा हूं। मैं आंकड़ा वस्तु भेजना चाहता हूं और उन्हें स्वयं इसके साथ इंटरैक्ट करना है।

जवाबों:


30

यह एक बड़ी विशेषता होगी, लेकिन AFAIK इसे Matplotlib में लागू नहीं किया गया है और संभवत: जिस तरह से आंकड़े संग्रहीत किए गए हैं, उसके कारण खुद को लागू करना मुश्किल होगा।

मैं या तो (a) आंकड़े को उत्पन्न करने से डेटा को अलग करने का सुझाव दूंगा (जो एक अद्वितीय नाम के साथ डेटा बचाता है) और एक आंकड़ा जनरेटिंग स्क्रिप्ट (सहेजे गए डेटा की एक निर्दिष्ट फ़ाइल लोड कर रहा है) लिखें और जैसा कि आप फिट देखें (b) ) पीडीएफ / एसवीजी / पोस्टस्क्रिप्ट प्रारूप के रूप में सहेजें और एडोब इलस्ट्रेटर (या इंकस्केप ) जैसे कुछ फैंसी फिगर संपादक में संपादित करें ।

EDIT पद पतन 2012 : जैसा कि अन्य लोगों ने नीचे बताया (हालांकि यहां उल्लेख किया गया है कि यह स्वीकृत उत्तर है), संस्करण 1.2 के बाद से Matplotlib ने आपको आंकड़े चुनने की अनुमति दी। रिलीज नोट्स राज्य के रूप में , यह एक प्रयोगात्मक विशेषता है और एक matplotlib संस्करण में एक आंकड़ा बचाने और दूसरे में खोलने का समर्थन नहीं करता है। यह भी आम तौर पर एक अविश्वसनीय स्रोत से एक अचार को बहाल करने के लिए असुरक्षित है।

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


2
कुछ आश्चर्य नहीं कि यह कार्यान्वित नहीं किया गया है .. लेकिन ठीक है, मैं एक मध्यवर्ती फ़ाइल में संसाधित डेटा को बचाऊंगा और सहयोगियों को साजिश रचने के लिए वह और एक स्क्रिप्ट भेजूंगा। धन्यवाद।
मैट

2
मुझे संदेह है कि कार्यान्वयन कठिन है, यही कारण है कि यह एक MATLAB इतना खराब काम करता है। वापस जब मैंने इसका इस्तेमाल किया, MATLAB को क्रैश करने के लिए इस्तेमाल किए गए आंकड़े, और यहां तक ​​कि थोड़ा अलग संस्करण एक-दूसरे की .fig फ़ाइलों को पढ़ने में सक्षम नहीं थे।
एड्रियन रत्नापाल

6
pickleअब एमपीएल आंकड़ों पर काम करता है, इसलिए यह किया जा सकता है और उचित रूप से काम करता प्रतीत होता है - लगभग एक मटलब ".फिग" आंकड़ा फ़ाइल की तरह। कैसे करना है, इसका एक उदाहरण के लिए नीचे (अब के लिए?) मेरा जवाब देखें।
डेमिस

@ डेमिस: जैसा कि पोटोमाटो ने नीचे दिए गए अपने जवाब में बताया, यह उस समय पहले से मौजूद था।
strpeter

@strpeter - Matlab के आंकड़े 2010 में पसंद नहीं किए गए थे क्योंकि इस टिप्पणी में बताया गया है । फाल्ट 2012 में जारी किए गए मैटलपोटलिब 1.2 के साथ प्रायोगिक सुविधा को जोड़ा गया था । जैसा कि वहाँ उल्लेख किया गया है, आपको यह उम्मीद नहीं करनी चाहिए कि यह matplotlib संस्करणों के बीच काम करेगा और आपको किसी अविश्वसनीय स्रोत से आने वाले अचार को नहीं खोलना चाहिए।
जिम्बॉब

63

मुझे अभी पता चला है कि यह कैसे करना है। @Pelson द्वारा उल्लिखित "प्रयोगात्मक अचार समर्थन" काफी अच्छी तरह से काम करता है।

इसे इस्तेमाल करे:

# Plot something
import matplotlib.pyplot as plt
fig,ax = plt.subplots()
ax.plot([1,2,3],[10,-10,30])

अपनी इंटरेक्टिव ट्विकिंग के बाद, फिगर ऑब्जेक्ट को एक बाइनरी फाइल के रूप में सहेजें:

import pickle
pickle.dump(fig, open('FigureObject.fig.pickle', 'wb')) # This is for Python 3 - py2 may need `file` instead of `open`

बाद में, आंकड़ा खोलें और ट्वीक्स को बचाया जाना चाहिए और GUI अन्तरक्रियाशीलता मौजूद होनी चाहिए:

import pickle
figx = pickle.load(open('FigureObject.fig.pickle', 'rb'))

figx.show() # Show the figure, edit it, etc.!

तुम भी भूखंडों से डेटा निकाल सकते हैं:

data = figx.axes[0].lines[0].get_data()

(यह लाइनों के लिए काम करता है, PColor और imshow - pcolormesh कुछ चाल के साथ काम करता है चपटा डेटा को फिर से संगठित करने के लिए ।)

मुझे अचार के इस्तेमाल से सेविंग मैटलपोटलिब फिगर्स से बहुत बढ़िया टिप मिला ।


मेरा मानना ​​है कि यह संस्करण परिवर्तन आदि के लिए मजबूत नहीं है, और py2.x & py3.x के बीच क्रॉस-संगत नहीं है। इसके अलावा, मुझे लगा कि pickleप्रलेखन में कहा गया है कि हमें पर्यावरण को उसी तरह से सेटअप करने की आवश्यकता है जब ऑब्जेक्ट को पिक किया गया था (सहेजा गया), लेकिन मैंने पाया है कि आपको import matplotlib.pyplot as pltअनप्लिकिंग (लोडिंग) करने की आवश्यकता नहीं है - यह आयात किए गए फ़ाइल में आयात विवरण बचाता है ।
डेमिस

5
आपको खुली हुई फाइलों को बंद करने पर विचार करना चाहिए: जैसेwith open('FigureObject.fig.pickle', 'rb') as file: figx = pickle.load(file)
स्ट्रैचर

1
मैं अभी प्राप्त करता हूं: 'AttractError:' चित्रा 'ऑब्जेक्ट में कोई विशेषता नहीं है' _cachedRenderer ''
user2673238

यदि आप नहीं चाहते हैं कि स्क्रिप्ट जारी रहे और संभवतः तुरंत बाद समाप्त हो जाए figx.show(), तो आपको plt.show()इसके बजाय कॉल करना चाहिए , जो अवरुद्ध है।
माचेलर

38

Matplotlib 1.2 के रूप में, अब हमारे पास प्रायोगिक अचार का समर्थन है। यह बताएं कि यह देखें कि क्या यह आपके मामले के लिए अच्छा है। यदि आपके पास कोई समस्या है, तो कृपया हमें Matplotlib मेलिंग सूची पर या github.com/matplotlib/matplotlib पर एक समस्या खोलकर बताएं


2
किसी भी कारण से इस उपयोगी सुविधा को "स्वयं के रूप में सहेजें" आंकड़े में जोड़ा जा सकता है। जोड़ना .pkl शायद?
ढिंचैक

अच्छा विचार है यदि आप इसे लागू करना चाहते हैं तो मैं इसका समर्थन करूंगा?
पेलसन

1
क्या यह केवल बैकएंड के सबसेट पर काम करता है? जब मैं OSX में एक साधारण आंकड़ा चुनने का प्रयास करता हूं, तो मुझे मिलता है PicklingError: Can't pickle <type '_macosx.GraphicsContext'>: it's not found as _macosx.GraphicsContext
फेनोरथ

उपरोक्त PicklingErrorकेवल तभी होता है जब आप plt.show()अचार करने से पहले कॉल करते हैं। तो बस के plt.show()बाद जगह है pickle.dump()
सालोमनवह

MacOS 10.11 पर मेरे py3.5 पर, इस fig.show()बात का कोई फर्क नहीं पड़ता है - शायद वह बग ठीक हो गया था। मैं show()बिना मुद्दे के पहले / बाद में अचार कर सकता हूं ।
डेमिस

7

सिर्फ पायथन लिपि ही क्यों न भेजें? MATLAB की .fig फ़ाइलों को प्राप्त करने के लिए MATLAB के लिए प्राप्तकर्ता की आवश्यकता होती है, इसलिए यह एक पायथन स्क्रिप्ट भेजने के बराबर है जिसे प्रदर्शित करने के लिए Matplotlib की आवश्यकता होती है।

वैकल्पिक रूप से (अस्वीकरण: मैंने अभी तक यह कोशिश नहीं की है), आप आंकड़ा चुनने की कोशिश कर सकते हैं:

import pickle
output = open('interactive figure.pickle', 'wb')
pickle.dump(gcf(), output)
output.close()

3
दुर्भाग्य से, matplotlib के आंकड़े अचूक नहीं हैं, इसलिए यह दृष्टिकोण काम नहीं करेगा। पर्दे के पीछे, बहुत सारे सी एक्सटेंशन हैं जो अचार का समर्थन नहीं करते हैं। मैं पूरी तरह से केवल स्क्रिप्ट + डेटा भेजने पर सहमत हूं, हालांकि ... मुझे लगता है कि मैंने वास्तव में कभी भी मतलाब के सहेजे जाने के बिंदु को नहीं देखा है। है, इसलिए मैंने कभी भी उनका उपयोग नहीं किया। किसी भी स्टैंड-अलोन कोड और डेटा को भेजना लंबे समय में मेरे अनुभव में सबसे आसान रहा है, वैसे भी। फिर भी, यह अच्छा होगा यदि matplotlib के आंकड़े ऑब्जेक्ट्स जहां पिकलेबल हैं।
जो किंग्सटन

1
यहां तक ​​कि हमारे पूर्वनिर्मित डेटा कुछ बड़ा है और साजिश रचने की प्रक्रिया जटिल है। हालांकि एकमात्र सहारा लगता है। धन्यवाद।
मैट

1
आंकड़े स्पष्ट रूप से अब पसंद करने योग्य हैं - यह काफी अच्छी तरह से काम करता है! नीचे उदाहरण है।
डेमिस

अचार का लाभ यह है कि आपको प्रोग्राम करने के लिए सभी आकृति / सबप्लॉट स्पेसिंग / पदों को समायोजित करने की आवश्यकता नहीं है। आप आकृति को अच्छा बनाने आदि के लिए MPL प्लॉट के GUI का उपयोग कर सकते हैं, फिर MyPlot.fig.pickleफ़ाइल को बचा सकते हैं - प्लॉट प्रस्तुति को आवश्यकतानुसार समायोजित करने की बाद की क्षमता को बनाए रखें। यह भी Matlab की .figफ़ाइलों के बारे में बहुत अच्छा है । विशेष रूप से उपयोगी है जब आपको एक अंजीर के आकार / पहलू अनुपात को बदलने (प्रस्तुतियों / कागजात में सम्मिलित करने के लिए) की आवश्यकता होती है।
डेमिस

1

अच्छा प्रश्न। यहाँ से डॉक्टर पाठ है pylab.save:

पाइलैब अब एक सेव फंक्शन प्रदान नहीं करता है, हालांकि पुराने पाइलैब फ़ंक्शन अभी भी matplotlib.mlab.save के रूप में उपलब्ध है (आप अभी भी पाइलैब में इसे "mlab.save" के रूप में संदर्भित कर सकते हैं)। हालाँकि, सादे पाठ फ़ाइलों के लिए, हम numpy.savetxt की सलाह देते हैं। सुन्न सरणियों को बचाने के लिए, हम numpy.save और इसके अनुरूप numpy.load की सलाह देते हैं, जो कि pylab में np.save और np.load के रूप में उपलब्ध हैं।


यह पाइलैब ऑब्जेक्ट से डेटा को बचाता है, लेकिन आपको आंकड़ा फिर से बनाने की अनुमति नहीं देता है।
जिम्बॉब डे

सही बात। मुझे यह स्पष्ट करना चाहिए कि उत्तर का उपयोग करने की सिफारिश नहीं थी pylab.save। वास्तव में, डॉक्स पाठ से, यह प्रतीत होता है कि किसी को इसका उपयोग नहीं करना चाहिए ।
स्टीव टोज़ा

3 डी फिगर भेजने के लिए क्या कोई बाहरी तरीका है? संभव भी एक सरल जीयूआई exe करने के लिए ..
CromeX

0

मुझे अपने मैटलपोटलिब के आंकड़ों को बचाने के लिए एक अपेक्षाकृत सरल तरीका (अभी तक थोड़ा अपरंपरागत) लगा। यह इस तरह काम करता है:

import libscript

import matplotlib.pyplot as plt
import numpy as np

t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2*np.pi*t)

#<plot>
plt.plot(t, s)
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.grid(True)
plt.show()
#</plot>

save_plot(fileName='plot_01.py',obj=sys.argv[0],sel='plot',ctx=libscript.get_ctx(ctx_global=globals(),ctx_local=locals()))

save_plotइस तरह परिभाषित समारोह के साथ (तर्क को समझने के लिए सरल संस्करण):

def save_plot(fileName='',obj=None,sel='',ctx={}):
    """
    Save of matplolib plot to a stand alone python script containing all the data and configuration instructions to regenerate the interactive matplotlib figure.

    Parameters
    ----------
    fileName : [string] Path of the python script file to be created.
    obj : [object] Function or python object containing the lines of code to create and configure the plot to be saved.
    sel : [string] Name of the tag enclosing the lines of code to create and configure the plot to be saved.
    ctx : [dict] Dictionary containing the execution context. Values for variables not defined in the lines of code for the plot will be fetched from the context.

    Returns
    -------
    Return ``'done'`` once the plot has been saved to a python script file. This file contains all the input data and configuration to re-create the original interactive matplotlib figure.
    """
    import os
    import libscript

    N_indent=4

    src=libscript.get_src(obj=obj,sel=sel)
    src=libscript.prepend_ctx(src=src,ctx=ctx,debug=False)
    src='\n'.join([' '*N_indent+line for line in src.split('\n')])

    if(os.path.isfile(fileName)): os.remove(fileName)
    with open(fileName,'w') as f:
        f.write('import sys\n')
        f.write('sys.dont_write_bytecode=True\n')
        f.write('def main():\n')
        f.write(src+'\n')

        f.write('if(__name__=="__main__"):\n')
        f.write(' '*N_indent+'main()\n')

return 'done'

या save_plotइस तरह के कार्य को परिभाषित करना (लाइटर फिगर फ़ाइलों का उत्पादन करने के लिए ज़िप संपीड़न का उपयोग करके बेहतर संस्करण):

def save_plot(fileName='',obj=None,sel='',ctx={}):

    import os
    import json
    import zlib
    import base64
    import libscript

    N_indent=4
    level=9#0 to 9, default: 6
    src=libscript.get_src(obj=obj,sel=sel)
    obj=libscript.load_obj(src=src,ctx=ctx,debug=False)
    bin=base64.b64encode(zlib.compress(json.dumps(obj),level))

    if(os.path.isfile(fileName)): os.remove(fileName)
    with open(fileName,'w') as f:
        f.write('import sys\n')
        f.write('sys.dont_write_bytecode=True\n')
        f.write('def main():\n')
        f.write(' '*N_indent+'import base64\n')
        f.write(' '*N_indent+'import zlib\n')
        f.write(' '*N_indent+'import json\n')
        f.write(' '*N_indent+'import libscript\n')
        f.write(' '*N_indent+'bin="'+str(bin)+'"\n')
        f.write(' '*N_indent+'obj=json.loads(zlib.decompress(base64.b64decode(bin)))\n')
        f.write(' '*N_indent+'libscript.exec_obj(obj=obj,tempfile=False)\n')

        f.write('if(__name__=="__main__"):\n')
        f.write(' '*N_indent+'main()\n')

return 'done'

यह libscriptमेरे खुद के एक मॉड्यूल का उपयोग करता है, जो ज्यादातर मॉड्यूल पर निर्भर करता है inspectऔर ast। यदि ब्याज व्यक्त किया जाता है, तो मैं इसे गितुब पर साझा करने का प्रयास कर सकता हूं (इसे पहले कुछ सफाई की आवश्यकता होगी और मुझे गितूब के साथ शुरू करने की आवश्यकता होगी)।

इस save_plotफ़ंक्शन और libscriptमॉड्यूल के पीछे का विचार अजगर के निर्देशों को प्राप्त करना है जो आंकड़ा (मॉड्यूल का उपयोग करके inspect) बनाते हैं , उन्हें विश्लेषण करते हैं (मॉड्यूल का उपयोग करके ast) सभी चर, फ़ंक्शन और मॉड्यूल आयात करते हैं जो इस पर निर्भर करते हैं, निष्पादन संदर्भ से इन्हें निकालें और इन्हें क्रमबद्ध करें। अजगर निर्देशों के रूप में (चर के लिए कोड की तरह होगा t=[0.0,2.0,0.01]... और मॉड्यूल के लिए कोड की तरह होगा import matplotlib.pyplot as plt...) आंकड़ा निर्देशों के लिए तैयार है। परिणामस्वरूप अजगर निर्देशों को एक अजगर स्क्रिप्ट के रूप में सहेजा जाता है, जिसका निष्पादन मूल matplotlib आकृति को फिर से बनाएगा।

जैसा कि आप कल्पना कर सकते हैं, यह सबसे (अगर सभी के लिए नहीं) matplotlib आंकड़ों के लिए अच्छी तरह से काम करता है।

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