Here is some example code showing how to define some representative rc properties and construct a Matplotlib artist using traits. Matplotlib does not ship with enthought.traits, so you will need to install it separately.
from __future__ import print_function
import sys
import os
import re
import traits.api as traits
from matplotlib.artist import Artist
doprint = True
flexible_true_trait = traits.Trait(
True,
{'true': True, 't': True, 'yes': True, 'y': True, 'on': True, True: True,
'false': False, 'f': False, 'no': False, 'n': False, 'off': False, False: False
})
flexible_false_trait = traits.Trait(False, flexible_true_trait)
colors = {
'c': '#00bfbf',
'b': '#0000ff',
'g': '#008000',
'k': '#000000',
'm': '#bf00bf',
'r': '#ff0000',
'w': '#ffffff',
'y': '#bfbf00',
'gold': '#FFD700',
'peachpuff': '#FFDAB9',
'navajowhite': '#FFDEAD',
}
def hex2color(s):
"Convert hex string (like html uses, eg, #efefef) to a r,g,b tuple"
return tuple([int(n, 16)/255.0 for n in (s[1:3], s[3:5], s[5:7])])
class RGBA(traits.HasTraits):
# r,g,b,a in the range 0-1 with default color 0,0,0,1 (black)
r = traits.Range(0., 1., 0.)
g = traits.Range(0., 1., 0.)
b = traits.Range(0., 1., 0.)
a = traits.Range(0., 1., 1.)
def __init__(self, r=0., g=0., b=0., a=1.):
self.r = r
self.g = g
self.b = b
self.a = a
def __repr__(self):
return 'r,g,b,a = (%1.2f, %1.2f, %1.2f, %1.2f)' %\
(self.r, self.g, self.b, self.a)
def tuple_to_rgba(ob, name, val):
tup = [float(x) for x in val]
if len(tup) == 3:
r, g, b = tup
return RGBA(r, g, b)
elif len(tup) == 4:
r, g, b, a = tup
return RGBA(r, g, b, a)
else:
raise ValueError
tuple_to_rgba.info = 'a RGB or RGBA tuple of floats'
def hex_to_rgba(ob, name, val):
rgx = re.compile('^#[0-9A-Fa-f]{6}$')
if not isinstance(val, six.string_types):
raise TypeError
if rgx.match(val) is None:
raise ValueError
r, g, b = hex2color(val)
return RGBA(r, g, b, 1.0)
hex_to_rgba.info = 'a hex color string'
def colorname_to_rgba(ob, name, val):
hex = colors[val.lower()]
r, g, b = hex2color(hex)
return RGBA(r, g, b, 1.0)
colorname_to_rgba.info = 'a named color'
def float_to_rgba(ob, name, val):
val = float(val)
return RGBA(val, val, val, 1.)
float_to_rgba.info = 'a grayscale intensity'
Color = traits.Trait(RGBA(), float_to_rgba, colorname_to_rgba, RGBA,
hex_to_rgba, tuple_to_rgba)
def file_exists(ob, name, val):
fh = file(val, 'r')
return val
linestyles = ('-', '--', '-.', ':', 'steps', 'None')
TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN = range(4)
linemarkers = (None, '.', ',', 'o', '^', 'v', '<', '>', 's',
'+', 'x', 'd', 'D', '|', '_', 'h', 'H',
'p', '1', '2', '3', '4',
TICKLEFT,
TICKRIGHT,
TICKUP,
TICKDOWN,
'None'
)
class LineRC(traits.HasTraits):
linewidth = traits.Float(0.5)
linestyle = traits.Trait(*linestyles)
color = Color
marker = traits.Trait(*linemarkers)
markerfacecolor = Color
markeredgecolor = Color
markeredgewidth = traits.Float(0.5)
markersize = traits.Float(6)
antialiased = flexible_true_trait
data_clipping = flexible_false_trait
class PatchRC(traits.HasTraits):
linewidth = traits.Float(1.0)
facecolor = Color
edgecolor = Color
antialiased = flexible_true_trait
timezones = 'UTC', 'US/Central', 'ES/Eastern' # fixme: and many more
backends = ('GTKAgg', 'Cairo', 'GDK', 'GTK', 'Agg',
'GTKCairo', 'PS', 'SVG', 'Template', 'TkAgg',
'WX')
class RC(traits.HasTraits):
backend = traits.Trait(*backends)
interactive = flexible_false_trait
toolbar = traits.Trait('toolbar2', 'classic', None)
timezone = traits.Trait(*timezones)
lines = traits.Trait(LineRC())
patch = traits.Trait(PatchRC())
rc = RC()
rc.lines.color = 'r'
if doprint:
print('RC')
rc.print_traits()
print('RC lines')
rc.lines.print_traits()
print('RC patches')
rc.patch.print_traits()
class Patch(Artist, traits.HasTraits):
linewidth = traits.Float(0.5)
facecolor = Color
fc = facecolor
edgecolor = Color
fill = flexible_true_trait
def __init__(self,
edgecolor=None,
facecolor=None,
linewidth=None,
antialiased=None,
fill=1,
**kwargs
):
Artist.__init__(self)
if edgecolor is None:
edgecolor = rc.patch.edgecolor
if facecolor is None:
facecolor = rc.patch.facecolor
if linewidth is None:
linewidth = rc.patch.linewidth
if antialiased is None:
antialiased = rc.patch.antialiased
self.edgecolor = edgecolor
self.facecolor = facecolor
self.linewidth = linewidth
self.antialiased = antialiased
self.fill = fill
p = Patch()
p.facecolor = '#bfbf00'
p.edgecolor = 'gold'
p.facecolor = (1, .5, .5, .25)
p.facecolor = 0.25
p.fill = 'f'
print('p.facecolor', type(p.facecolor), p.facecolor)
print('p.fill', type(p.fill), p.fill)
if p.fill_:
print('fill')
else:
print('no fill')
if doprint:
print()
print('Patch')
p.print_traits()