Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f4b589b

Browse files
committed
DOC : move MEP26
1 parent a295d54 commit f4b589b

File tree

2 files changed

+233
-0
lines changed

2 files changed

+233
-0
lines changed

doc/devel/MEP/MEP26.rst

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
=======================
2+
MEP26: Artist styling
3+
=======================
4+
5+
.. contents::
6+
:local:
7+
8+
9+
Status
10+
======
11+
12+
**Proposed**
13+
14+
Branches and Pull requests
15+
==========================
16+
17+
Abstract
18+
========
19+
20+
This MEP proposes a new stylesheet implementation to allow more
21+
comprehensive and dynamic styling of artists.
22+
23+
The current version of matplotlib (1.4.0) allows stylesheets based on
24+
the rcParams syntax to be applied before creation of a plot. The
25+
methodology below proposes a new syntax, based on CSS, which would
26+
allow styling of individual artists and properties, which can be
27+
applied dynamically to existing objects.
28+
29+
This is related to (and makes steps toward) the overall goal of moving
30+
to a DOM/tree-like architecture.
31+
32+
33+
Detailed description
34+
====================
35+
36+
Currently, the look and appearance of existing artist objects (figure,
37+
axes, Line2D etc...) can only be updated via `set_` and `get_` methods
38+
on the artist object, which is quite laborious, especially if no
39+
reference to the artist(s) has been stored. The new style sheets
40+
introduced in 1.4 allow styling before a plot is created, but do not
41+
offer any means to dynamically update plots or distinguish between
42+
artists of the same type (i.e. to specifiy the `line color` and `line
43+
style` separately for differing `Line2D` objects).
44+
45+
The initial development should concentrate on allowing styling of
46+
artist primitives (those `artists` that do not contain other
47+
`artists`), and further development could expand the CSS syntax rules
48+
and parser to allow more complex styling. See the appendix for a list
49+
of primitives.
50+
51+
The new methodology would require development of a number of steps:
52+
53+
- A new stylesheet syntax (likely based on CSS) to allow selection of
54+
artists by type, class, id etc...
55+
- A mechanism by which to parse a stylesheet into a tree
56+
- A mechanism by which to translate the parse-tree into something
57+
which can be used to update the properties of relevant
58+
artists. Ideally this would implement a method by which to traverse
59+
the artists in a tree-like structure.
60+
- A mechanism by which to generate a stylesheet from existing artist
61+
properties. This would be useful to allow a user to export a
62+
stylesheet from an existing figure (where the appearance may have
63+
been set using the matplotlib API)...
64+
65+
Implementation
66+
==============
67+
68+
It will be easiest to allow a '3rd party' to modify/set the style of
69+
an artist if the 'style' is created as a separate class and store
70+
against the artist as a property. The `GraphicsContext` class already
71+
provides a the basis of a `Style` class and an artists `draw` method can
72+
be refactored to use the `Style` class rather than setting up it's own
73+
`GraphicsContext` and transferring it's style-related properties to
74+
it. A minimal example of how this could be implemented is shown here:
75+
https://github.com/JamesRamm/mpl_experiment
76+
77+
IMO, this will also make the API and code base much neater as
78+
individual get/set methods for artist style properties are now
79+
redundant... Indirectly related would be a general drive to replace
80+
get/set methods with properties. Implementing the style class with
81+
properties would be a big stride toward this...
82+
83+
For initial development, I suggest developing a syntax based on a much
84+
(much much) simplified version of CSS. I am in favour of dubbing this
85+
Artist Style Sheets :+1: :
86+
87+
BNF Grammar
88+
-----------
89+
90+
I propose a very simple syntax to implement initially (like a proof of
91+
concept), which can be expanded upon in the future. The BNF form of
92+
the syntax is given below and then explained ::
93+
94+
RuleSet ::= SelectorSequence "{"Declaration"}"
95+
96+
SelectorSequence :: = Selector {"," Selector}
97+
98+
Declaration ::= propName":" propValue";"
99+
100+
Selector ::= ArtistIdent{"#"Ident}
101+
102+
propName ::= Ident
103+
104+
propValue ::= Ident | Number | Colour | "None"
105+
106+
`ArtistIdent`, `Ident`, `Number` and `Colour` are tokens (the basic
107+
building blocks of the expression) which are defined by regular
108+
expressions.
109+
110+
Syntax
111+
------
112+
113+
A CSS stylesheet consists of a series of **rule sets** in hierarchical
114+
order (rules are applied from top to bottom). Each rule follows the
115+
syntax ::
116+
117+
selector {attribute: value;}
118+
119+
Each rule can have any number of `attribute`:`value` pairs, and a
120+
stylesheet can have any number of rules.
121+
122+
The initial syntax is designed only for `artist` primitives. It does
123+
not address the question of how to set properties on `container` types
124+
(whose properties may themselves be `artists` with settable
125+
properties), however, a future solution to this could simply be nested
126+
`RuleSet`s
127+
128+
Selectors
129+
~~~~~~~~~
130+
131+
132+
Selectors define the object to which the attribute updates should be
133+
applied. As a starting point, I propose just 2 selectors to use in
134+
initial development:
135+
136+
137+
138+
Artist Type Selector
139+
140+
141+
Select an `artist` by it's type. E.g `Line2D` or `Text`::
142+
143+
Line2D {attribute: value}
144+
145+
The regex for matching the artist type selector (`ArtistIdent` in the BNF grammar) would be::
146+
147+
ArtistIdent = r'(?P<ArtistIdent>\bLine2D\b|\bText\b|\bAxesImage\b|\bFigureImage\b|\bPatch\b)'
148+
149+
GID selector
150+
~~~~~~~~~~~~
151+
152+
Select an `artist` by its `gid`::
153+
154+
Line2D#myGID {attribute: value}
155+
156+
A `gid` can be any string, so the regex could be as follows::
157+
158+
Ident = r'(?P<Ident>[a-zA-Z_][a-zA-Z_0-9]*)'
159+
160+
161+
The above selectors roughly correspond to their CSS counterparts
162+
(http://www.w3.org/TR/CSS21/selector.html)
163+
164+
Attributes and values
165+
~~~~~~~~~~~~~~~~~~~~~
166+
167+
- `Attributes` are any valid (settable) property for the `artist` in question.
168+
- `Values` are any valid value for the property (Usually a string, or number).
169+
170+
Parsing
171+
-------
172+
173+
Parsing would consist of breaking the stylesheet into tokens (the
174+
python cookbook gives a nice tokenizing recipe on page 66), applying
175+
the syntax rules and constructing a `Tree`. This requires defining the
176+
grammar of the stylesheet (again, we can borrow from CSS) and writing
177+
a parser. Happily, there is a recipe for this in the python cookbook
178+
aswell.
179+
180+
181+
Visitor pattern for matplotlib figure
182+
-------------------------------------
183+
184+
In order to apply the stylesheet rules to the relevant artists, we
185+
need to 'visit' each artist in a figure and apply the relevant rule.
186+
Here is a visitor class (again, thanks to python cookbook), where each
187+
`node` would be an artist in the figure. A `visit_` method would need
188+
to be implemented for each mpl artist, to handle the different
189+
properties for each ::
190+
191+
class Visitor:
192+
def visit(self, node):
193+
name = 'visit_' + type(node).__name__
194+
meth = getattr(self, name, None)
195+
if meth is None:
196+
raise NotImplementedError
197+
return meth(node)
198+
199+
An `evaluator` class would then take the stylesheet rules and
200+
implement the visitor on each one of them.
201+
202+
203+
204+
Backward compatibility
205+
======================
206+
207+
Implementing a separate `Style` class would break backward
208+
compatibility as many get/set methods on an artist would become
209+
redundant. While it would be possible to alter these methods to hook
210+
into the `Style` class (stored as a property against the artist), I
211+
would be in favor of simply removing them to both neaten/simplify the
212+
codebase and to provide a simple, uncluttered API...
213+
214+
Alternatives
215+
============
216+
217+
No alternatives, but some of the ground covered here overlaps with
218+
MEP25, which may assist in this development
219+
220+
Appendix
221+
========
222+
223+
Matplotlib primitives
224+
~~~~~~~~~~~~~~~~~~~~~
225+
226+
This will form the initial selectors which stylesheets can use.
227+
228+
* Line2D
229+
* Text
230+
* AxesImage
231+
* FigureImage
232+
* Patch

doc/devel/MEP/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ Matplotlib Enhancement Proposals
2727
MEP23
2828
MEP24
2929
MEP25
30+
MEP26

0 commit comments

Comments
 (0)