ฉันคิดหาวิธีที่ค่อนข้างง่าย (แต่แหวกแนวเล็กน้อย) ในการบันทึกตัวเลข 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()))
ด้วยฟังก์ชันที่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 ได้)
แนวคิดเบื้องหลังsave_plot
ฟังก์ชันและlibscript
โมดูลนี้คือการดึงคำสั่ง python ที่สร้างรูป (โดยใช้โมดูลinspect
) วิเคราะห์ (โดยใช้โมดูลast
) เพื่อแยกตัวแปรฟังก์ชั่นและโมดูลทั้งหมดที่นำเข้าซึ่งอาศัยแยกสิ่งเหล่านี้ออกจากบริบทการดำเนินการและทำให้เป็นอนุกรม ตามคำสั่ง python (โค้ดสำหรับตัวแปรจะเป็นเหมือนt=[0.0,2.0,0.01]
... และโค้ดสำหรับโมดูลจะเป็นเหมือนimport matplotlib.pyplot as plt
... ) นำหน้าคำสั่งรูป คำสั่ง python ที่ได้จะถูกบันทึกเป็นสคริปต์ python ซึ่งการดำเนินการจะสร้างรูป matplotlib ดั้งเดิมขึ้นมาใหม่
อย่างที่คุณสามารถจินตนาการได้ว่าสิ่งนี้ใช้ได้ดีกับตัวเลข matplotlib ส่วนใหญ่ (ถ้าไม่ใช่ทั้งหมด)