import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
from collections import OrderedDict
class Line2DController(object):
arg_pos = ['xdata', 'ydata', 'linewidth', 'linestyle', 'color', 'marker', 'markersize',
'markeredgewidth', 'markeredgecolor', 'markerfacecolor', 'markerfacecoloralt',
'fillstyle', 'antialiased', 'dash_capstyle', 'solid_capstyle', 'dash_joinstyle',
'pickradius', 'drawstyle', 'markevery']
defaults = dict(
linewidth=None,
linestyle=None,
color=None,
marker=None,
markersize=None,
markeredgewidth=None,
markeredgecolor=None,
markerfacecolor=None,
markerfacecoloralt=u'none',
fillstyle=u'full',
antialiased=None,
dash_capstyle=None,
solid_capstyle=None,
dash_joinstyle=None,
solid_joinstyle=None,
pickradius=5,
drawstyle=None,
markevery=None
)
def __init__(self, ax, *args, **kwargs):
for key, val in self.get_args_mapping(args).items():
setattr(self, key, val)
for key, val in kwargs.items():
if not hasattr(self, key):
setattr(self, key, val)
for key, val in self.defaults.items():
if not hasattr(self, key): # make sure it wasn't set already
setattr(self, key, val)
self.ax = ax
self.line = matplotlib.lines.Line2D(*args, **kwargs)
ax.add_line(self.line)
ax.relim()
ax.autoscale_view()
def redraw(self):
kwargs = self.get_attributes()
self.ax.lines.remove(self.line)
self.line = matplotlib.lines.Line2D(**kwargs)
self.ax.add_line(self.line)
ax.relim()
ax.autoscale_view()
def get_args_mapping(self, args):
d = {}
for iii, arg in enumerate(args):
d[self.arg_pos[iii]] = arg
return d
def get_attributes(self):
d = {}
for key in self.defaults:
d[key] = getattr(self, key)
d['xdata'] = self.xdata
d['ydata'] = self.ydata
return d
def __setitem__(self, key, val):
if key not in set.union(set(self.arg_pos), set(self.defaults)):
raise Exception("don't do that...")
else:
setattr(self, key, val)
self.redraw()
def to_json(self):
d = self.get_attributes()
return d
fig, ax = plt.subplots()
lc1 = Line2DController(ax, [1,2,3], [2,1,2])
lc2 = Line2DController(ax, **lc1.to_json()) # obviously, we need to work out the axes reference...
# this behavior is key, we want to be able to just set attributes with the controller
# this will allow simple eventual instantiation with `**kwargs`
lc1['color'] = 'r'
lc1['xdata'] = [2, 3, 4]
lc1['ydata'] = [10, 3, 6]
lc1['marker'] = 'o'
lc1['markeredgewidth'] = 10
lc1['linewidth'] = 10
fig
lc1.to_json()
{'antialiased': None, 'color': 'r', 'dash_capstyle': None, 'dash_joinstyle': None, 'drawstyle': None, 'fillstyle': u'full', 'linestyle': None, 'linewidth': 10, 'marker': 'o', 'markeredgecolor': None, 'markeredgewidth': 10, 'markerfacecolor': None, 'markerfacecoloralt': u'none', 'markersize': None, 'markevery': None, 'pickradius': 5, 'solid_capstyle': None, 'solid_joinstyle': None, 'xdata': [2, 3, 4], 'ydata': [10, 3, 6]}
lc2.to_json()
{'antialiased': None, 'color': None, 'dash_capstyle': None, 'dash_joinstyle': None, 'drawstyle': None, 'fillstyle': u'full', 'linestyle': None, 'linewidth': None, 'marker': None, 'markeredgecolor': None, 'markeredgewidth': None, 'markerfacecolor': None, 'markerfacecoloralt': u'none', 'markersize': None, 'markevery': None, 'pickradius': 5, 'solid_capstyle': None, 'solid_joinstyle': None, 'xdata': [1, 2, 3], 'ydata': [2, 1, 2]}