当前,我正在考虑保存一个未知状态的matplotlib图,因为它正对着用户。我打算执行此操作的方法是将数字放在首位,然后将首选项放入字典中。但是,可以通过将任何基本类型保存到字典中,然后利用json库保存并将该字典加载到文件中来实现。
总体目标是具有操作系统独立性和跨matplotlib版本的兼容性。
我已经原型化了,将绘图的首选项/设置保存到字典中:
import numpy as np
from matplotlib import ticker
import matplotlib.pyplot as plt
import matplotlib.colors
import json
def get_dict_from_fig(fig):
fig_dict = {}
axes_list = []
for ax in fig.axes:
axes_list.append(get_dict_for_axes(ax))
fig_dict["Axes"] = axes_list
fig_dict["Properties"] = get_dict_from_fig_properties(fig)
return fig_dict
def get_dict_for_axes(ax):
ax_dict = {}
# Get the axis properties
ax_dict["Properties"] = get_dict_from_axes_properties(ax)
# Get lines from the axes and store it's data
lines_list = []
for index, line in enumerate(ax.lines):
lines_list.append(get_dict_from_line(line, index))
ax_dict["Lines"] = lines_list
texts_list = []
for text in ax.texts:
texts_list.append(get_dict_from_text(text))
ax_dict["Texts"] = texts_list
ax_dict["Title"] = get_dict_from_text(ax.title)
ax_dict["XAxis Title"] = get_dict_from_text(ax.xaxis.label)
ax_dict["YAxis Title"] = get_dict_from_text(ax.yaxis.label)
# Potentially need to handle artists that are Text
artist_text_dict = {}
for artist in ax.artists:
if isinstance(artist, matplotlib.text.Text):
artist_text_dict = get_dict_from_text(artist)
ax_dict["Text from artists"] = artist_text_dict
legend_dict = {}
legend = ax.get_legend()
if legend is not None and legend.get_visible():
legend_dict = get_dict_from_legend(legend)
legend_dict["Visible"] = True
ax_dict["Legend"] = legend_dict
return ax_dict
def get_dict_from_axes_properties(ax):
prop_dict = {}
prop_dict["Bounds"] = ax.get_position().bounds
prop_dict["Dynamic"] = ax.get_navigate()
prop_dict["Axison"] = ax.axison
prop_dict["Frame On"] = ax.get_frame_on()
prop_dict["XAxis Properties"] = get_dict_from_axis_properties(ax.xaxis)
prop_dict["YAxis Properties"] = get_dict_from_axis_properties(ax.yaxis)
# XAxis scale and Xlim
prop_dict["XAxis Scale"] = ax.xaxis.get_scale()
prop_dict["XLim"] = ax.get_xlim()
# YAxis scale and Ylim
prop_dict["YAxis Scale"] = ax.xaxis.get_scale()
prop_dict["YLim"] = ax.get_ylim()
return prop_dict
def get_dict_from_axis_properties(ax):
prop_dict = {}
label1On = ax._major_tick_kw.get('label1On', True)
if isinstance(ax, matplotlib.axis.XAxis):
if label1On:
prop_dict["Position"] = "Bottom"
else:
prop_dict["Position"] = "Top"
elif isinstance(ax, matplotlib.axis.YAxis):
if label1On:
prop_dict["Position"] = "Left"
else:
prop_dict["Position"] = "Right"
else:
raise ValueError("Value passed is not a valid axis")
prop_dict["nTicks"] = len(ax.get_major_locator()())
if isinstance(ax.get_major_locator(), ticker.FixedLocator):
prop_dict["Tick Values"] = list(ax.get_major_locator())
else:
prop_dict["Tick Values"] = None
formatter = ax.get_major_formatter()
if isinstance(formatter, ticker.FixedFormatter):
prop_dict["Tick Format"] = list(formatter.seq)
else:
prop_dict["Tick Format"] = ""
labels = ax.get_ticklabels()
if labels:
prop_dict["Font size"] = labels[0].get_fontsize()
else:
prop_dict["Font size"] = ""
prop_dict["Scale"] = ax.get_scale()
prop_dict["Grid Style"] = get_dict_for_grid_style(ax)
prop_dict["Visible"] = ax.get_visible()
return prop_dict
def get_dict_for_grid_style(ax):
grid_style = {}
gridlines = ax.get_gridlines()
if ax._gridOnMajor and len(gridlines) > 0:
grid_style["Color"] = matplotlib.colors.to_hex(gridlines[0].get_color())
grid_style["Alpha"] = gridlines[0].get_alpha()
grid_style["Grid On"] = True
else:
grid_style["Grid On"] = False
return grid_style
def get_dict_from_line(line, index=0):
line_dict = {}
line_dict["Line Index"] = index
line_dict["Label"] = line.get_label()
line_dict["Alpha"] = line.get_alpha()
if line_dict["Alpha"] is None:
line_dict["Alpha"] = 1
line_dict["Color"] = matplotlib.colors.to_hex(line.get_color())
line_dict["Linewidth"] = line.get_linewidth()
line_dict["Line Style"] = line.get_linestyle()
line_dict["Marker Style"] = get_dict_from_marker_style(line)
return line_dict
def get_dict_from_marker_style(line):
style_dict = {}
style_dict["Face Color"] = matplotlib.colors.to_hex(line.get_markerfacecolor())
style_dict["Edge Color"] = matplotlib.colors.to_hex(line.get_markeredgecolor())
style_dict["Edge Width"] = line.get_markeredgewidth()
style_dict["Marker Type"] = line.get_marker()
style_dict["Marker Size"] = line.get_markersize()
style_dict["ZOrder"] = line.get_zorder()
return style_dict
def get_dict_from_text(text):
text_dict = {}
text_dict["Text"] = text.get_text()
if text_dict["Text"]:
text_dict["Transform"] = text.get_transform()
text_dict["Position"] = text.get_position()
text_dict["Style"] = get_dict_from_text_style(text)
return text_dict
def get_dict_from_text_style(text):
style_dict = {}
style_dict["Alpha"] = text.get_alpha()
if style_dict["Alpha"] is None:
style_dict["Alpha"] = 1
style_dict["Text Size"] = text.get_size()
style_dict["Color"] = matplotlib.colors.to_hex(text.get_color())
style_dict["hAlign"] = text.get_horizontalalignment()
style_dict["vAlign"] = text.get_verticalalignment()
style_dict["mAlign"] = text._multialignment
style_dict["Rotation"] = text.get_rotation()
style_dict["ZOrder"] = text.get_zorder()
return style_dict
def get_dict_from_legend(legend):
legend_dict = {}
legend_elements_list = get_list_of_legend_children(legend)
legend_elements_list.append(legend.legendPatch)
text_list = []
line_list = []
for child in legend_elements_list:
try:
if isinstance(child, matplotlib.text.Text):
if child.get_text() != None:
text_list.append(get_dict_from_text(child))
if isinstance(child, matplotlib.lines.Line2D):
line_list.append(get_dict_from_line(child))
except NotImplementedError:
# Basically do nothing
pass
legend_dict["Text"] = text_list
legend_dict["Line List"] = line_list
return legend_dict
def get_list_of_legend_children(legend):
legend_list = []
if hasattr(legend, 'get_children') and len(legend.get_children()) > 0:
for child in legend.get_children():
legend_list.append(get_list_of_legend_children(child))
else:
legend_list.append(legend)
return legend_list
def get_dict_from_fig_properties(fig):
fig_dict = {}
fig_dict["Fig width"] = fig.get_figwidth()
fig_dict["Fig height"] = fig.get_figheight()
fig_dict["dpi"] = fig.dpi
return fig_dict
XVals = np.array([1, 2, 3])
YVals = np.array([1, 2, 3])
plt.plot(XVals, YVals)
dictionary = get_dict_from_fig(plt.gcf())
f = open("./savefile.json", "w+")
f.write(json.dumps(dictionary, indent=4))
我想知道是否已经可以通过维护的库来执行此操作?我试图找到一些办法来做,除了灵感,我找不到任何有用的东西。我已经使用mpld3作为灵感。
我可能早些时候已经提到过这一点,但是在保存时,关键是要加载回已保存的数据,否则保存起来毫无意义。