prosource

대화형 Matplotlib 그림 저장

probook 2023. 7. 17. 21:12
반응형

대화형 Matplotlib 그림 저장

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

저는 이러한 상호작용적인 수치를 생성하기 위해 동일한 스크립트를 여러 번 실행하는 제 자신을 발견합니다.아니면 제 동료들에게 여러 개의 정적 PNG 파일을 보내서 플롯의 다른 측면을 보여주거나 합니다.저는 차라리 그림 객체를 보내고 그들이 직접 그것과 상호 작용하도록 하고 싶습니다.

어떻게 하는지 방금 알았어요.@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에 사용할 수 있습니다. pcolor 메시는 몇 가지 트릭으로 플랫 데이터를 재구성합니다.)

는 피클을 사용한 매트플롯립 피규어 저장에서 훌륭한 팁을 받았습니다.

Matplotlib 1.2부터는 실험적인 피클 지원을 제공합니다.그것을 한 번 해보고 당신의 경우에 효과가 있는지 확인해 보세요.문제가 있으면 Matplotlib 메일링 리스트나 github.com/matplotlib/matplotlib 에서 이슈를 오픈하여 알려주시기 바랍니다.

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

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

2012년 가을 이후 편집: 다른 사람들이 아래에서 지적했듯이(여기서 언급하는 것이 허용된 답변이지만), Matplotlib 버전 1.2부터 수치를 피클링할 수 있습니다.릴리스 정보에 나와 있듯이, 이 기능은 실험적인 기능이며 한 matplotlib 버전에 그림을 저장하고 다른 버전에 그림을 여는 것을 지원하지 않습니다.또한 신뢰할 수 없는 소스에서 피클을 복원하는 것은 일반적으로 안전하지 않습니다.

플롯을 공유/나중에 편집하는 경우(먼저 상당한 데이터 처리가 필요하고 몇 달 후에 수정해야 할 수도 있음), (1) 플롯을 생성하기 전에 처리된 데이터(플롯에 들어가는)를 파일로 저장하는 데이터 처리 스크립트를 준비하는 것이 좋습니다.및 (2) 별도의 플롯 생성 스크립트(필요에 따라 조정)를 사용하여 플롯을 재생성합니다.이렇게 하면 각 플롯에 대해 스크립트를 빠르게 실행하고 다시 생성할 수 있습니다(새 데이터로 플롯 설정 위에 빠르게 복사).즉, 단기/대화형/탐색형 데이터 분석에는 수치를 고르는 것이 편리할 수 있습니다.

Python 스크립트만 보내는 게 어때요? 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를 사용하는 것이 좋습니다.tex를 절약합니다.Numpy 배열을 저장하려면 Numpy를 사용하는 것이 좋습니다.np.save 및 np.load로 사용할 수 있는 아날로그 numpy.load를 지정합니다.

저는 매트플롯립 수치를 저장하는 비교적 간단한 방법(하지만 약간은 파격적)을 찾았습니다.다음과 같이 작동합니다.

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이와 같이(좀 더 가벼운 그림 파일을 생성하기 위해 zip 압축을 사용하는 더 나은 버전):

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관심이 표명되면 Github에서 공유할 수 있습니다(Github을 시작하려면 먼저 정리와 제가 필요합니다).

것의이있는생각에면이▁▁behind생각의 아이디어.save_plot 및 기능및libscript입니다.inspect하여) , (모듈을 사용하여)ast 변수, 및 가져오기를 는 ) 모든변수함, 가기를오변이추서러져에변한면트려명수를다고출추하행령니직같다수합니 python어습과화음다렬로는수드코텍실스출컨듈하모및변▁)▁import▁)▁it▁for다니습code▁extract▁to▁relies▁like,ize같▁and▁instruct▁will과,▁on▁variables음다▁extract▁and(▁modules명▁themions▁(▁be는드다▁python▁context코.t=[0.0,2.0,0.01]모듈 코드는 다음과 같습니다.import matplotlib.pyplot as plt그림 지침 앞에 ...을 추가합니다.결과로 생성된 파이썬 명령어는 원래 matplotlib 피규어를 다시 빌드하는 파이썬 스크립트로 저장됩니다.

여러분이 상상할 수 있듯이, 이것은 (전부는 아니더라도) 대부분의 매트플롯립 수치에서 잘 작동합니다.

만약 당신이 파이썬 플롯을 수정하고 MATLAB.fig 파일과 같은 다른 사람들과 공유하기 위해 대화형 피규어로 저장하려고 한다면, 당신은 다음 코드를 사용할 수 있습니다.여기서z_data.values는 단순한 numpind 배열이므로 동일한 코드를 사용하여 자신의 데이터를 플롯하고 저장할 수 있습니다.그렇다면 팬더를 사용할 필요가 없습니다.

여기서 생성된 파일은 클릭만 하면 파이썬이 있든 없든 누구나 열고 대화식으로 수정할 수 있으며 크롬/파이어폭스/엣지 등의 브라우저에서 열 수 있습니다.

import plotly.graph_objects as go
import pandas as pd

z_data=pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')

fig = go.Figure(data=[go.Surface(z=z_data.values)])

fig.update_layout(title='Mt Bruno Elevation', autosize=False,
                  width=500, height=500,
                  margin=dict(l=65, r=50, b=65, t=90))

fig.show()
fig.write_html("testfile.html")

언급URL : https://stackoverflow.com/questions/4348733/saving-interactive-matplotlib-figures

반응형