program tip

대화 형 Matplotlib 그림 저장

radiobox 2020. 8. 10. 07:52
반응형

대화 형 Matplotlib 그림 저장


다시 열 수 있고 일반적인 상호 작용을 복원 할 수 있도록 Matplotlib 그림을 저장하는 방법이 있습니까? (MATLAB의 .fig 형식과 비슷합니까?)

이러한 대화 형 그림을 생성하기 위해 동일한 스크립트를 여러 번 실행하고 있습니다. 또는 동료들에게 여러 개의 정적 PNG 파일을 보내 플롯의 다양한 측면을 보여줍니다. 차라리 피겨 객체를 보내고 그들 스스로 상호 작용하게하고 싶습니다.


이것은 훌륭한 기능이지만 AFAIK는 Matplotlib에서 구현되지 않으며 수치가 저장되는 방식으로 인해 직접 구현하기 어려울 수 있습니다.

(a) 그림 생성 (고유 한 이름으로 데이터 저장)에서 데이터 처리를 분리하고 그림 생성 스크립트 (저장된 데이터의 지정된 파일로드)를 작성하고 적합하다고 생각되는대로 편집하거나 (b) ) PDF / SVG / PostScript 형식으로 저장하고 Adobe Illustrator (또는 Inkscape ) 와 같은 멋진 그림 편집기에서 편집 합니다.

편집 게시물 Fall 2012 : 다른 사람들이 아래에서 지적했듯이 (여기에 이것이 허용되는 대답이라고 언급했지만) 버전 1.2 이후 Matplotlib는 수치를 피클 할 수있었습니다. 릴리스 노트에 명시되어 있듯이 이는 실험적 기능이며 한 matplotlib 버전에서 Figure를 저장하고 다른 버전에서 여는 것을 지원하지 않습니다. 신뢰할 수없는 출처에서 피클을 복원하는 것도 일반적으로 안전하지 않습니다.

플롯을 공유 / 나중에 편집하려면 (먼저 중요한 데이터 처리가 필요하고 과학 간행물에 대한 동료 검토 중에 몇 달 후에 조정해야 할 수 있음) 플롯을 생성하기 전에 (1)의 워크 플로를 사용하는 것이 좋습니다. 처리 된 데이터 (플롯으로 이동)를 파일에 저장하고 (2) 별도의 플롯 생성 스크립트 (필요에 따라 조정)를 사용하여 플롯을 다시 생성합니다. 이렇게하면 각 플롯에 대해 스크립트를 빠르게 실행하고 다시 생성 할 수 있습니다 (새 데이터로 플롯 설정을 빠르게 복사). 즉, 수치를 산세하는 것은 단기 / 대화 형 / 탐색 데이터 분석에 편리 할 수 ​​있습니다.


이 작업을 수행하는 방법을 방금 찾았습니다. @pelson이 언급 한 "실험적 피클 지원"은 매우 잘 작동합니다.

이 시도:

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

대화 형 조정 후 Figure 개체를 이진 파일로 저장합니다.

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는 평면화 된 데이터를 재구성하는 몇 가지 트릭과 함께 작동합니다 .)

Pickle을 사용하여 Matplotlib Figures 저장 에서 훌륭한 팁을 얻었습니다 .


Matplotlib 1.2부터 실험적인 피클 지원이 제공됩니다. 그것을 시도하고 그것이 당신의 경우에 잘 작동하는지 확인하십시오. 문제가있는 경우 Matplotlib 메일 링리스트 또는 github.com/matplotlib/matplotlib 에서 문제를 열어 알려주십시오 .


왜 파이썬 스크립트를 보내지 않습니까? MATLAB의 .fig 파일은 수신자에게 MATLAB이이를 표시하도록 요구하므로 표시하는 데 Matplotlib가 필요한 Python 스크립트를 보내는 것과 거의 같습니다.

또는 (면책 조항 : 아직 시도하지 않았습니다) 그림을 산세 할 수 있습니다.

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

좋은 질문. 다음은의 문서 텍스트입니다 pylab.save.

이전 pylab 함수는 여전히 matplotlib.mlab.save로 사용할 수 있지만 pylab은 더 이상 저장 기능을 제공하지 않습니다 (pylab에서 "mlab.save"로 계속 참조 할 수 있음). 그러나 일반 텍스트 파일의 경우 numpy.savetxt를 권장합니다. numpy 배열을 저장하려면 numpy.save 및 pylab에서 np.save 및 np.load로 사용할 수있는 아날로그 numpy.load를 권장합니다.


나는 matplotlib 수치를 저장하는 비교적 간단한 방법 (그러나 약간 비 전통적인 방법)을 알아 냈습니다. 다음과 같이 작동합니다.

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

with function save_plot defined like this (simple version to understand the logic):

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'

or defining function save_plot like this (better version using zip compression to produce lighter figure files):

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'

This makes use a module libscript of my own, which mostly relies on modules inspect and ast. I can try to share it on Github if interest is expressed (it would first require some cleanup and me to get started with Github).

The idea behind this save_plot function and libscript module is to fetch the python instructions that create the figure (using module inspect), analyze them (using module ast) to extract all variables, functions and modules import it relies on, extract these from the execution context and serialize them as python instructions (code for variables will be like t=[0.0,2.0,0.01] ... and code for modules will be like import matplotlib.pyplot as plt ...) prepended to the figure instructions. The resulting python instructions are saved as a python script whose execution will re-build the original matplotlib figure.

As you can imagine, this works well for most (if not all) matplotlib figures.

참고URL : https://stackoverflow.com/questions/4348733/saving-interactive-matplotlib-figures

반응형