MEP26:艺术家造型#
状态#
被拒绝
分支和拉取请求#
摘要#
该 MEP 提出了一种新的样式表实现,以允许对艺术家进行更全面和动态的样式设置。
当前版本的 matplotlib (1.4.0) 允许在创建绘图之前应用基于 rcParams 语法的样式表。下面的方法提出了一种基于 CSS 的新语法,它允许对单个艺术家和属性进行样式设置,可以动态地应用于现有对象。
这与迁移到类似 DOM/树的架构的总体目标相关(并朝着这些目标迈进了一步)。
详细说明#
目前,现有艺术家对象(图形、轴、Line2D 等)的外观只能通过艺术家对象上的set_
和get_
方法进行更新,这非常费力,尤其是在没有存储对艺术家的引用的情况下. 1.4 中引入的新样式表允许在创建绘图之前进行样式设置,但不提供任何方法来动态更新绘图或区分相同类型的艺术家(即为不同的对象分别指定和)。line color
line
style
Line2D
最初的开发应该集中于允许艺术家原语的样式(那些Artist
不包含其他
Artist
s 的 s),进一步的开发可以扩展 CSS 语法规则和解析器以允许更复杂的样式。有关原语列表,请参见附录。
新方法将需要制定一些步骤:
一种新的样式表语法(可能基于 CSS),允许按类型、类、id 等选择艺术家。
一种将样式表解析为树的机制
一种将解析树转换为可用于更新相关艺术家属性的机制。理想情况下,这将实现一种在树状结构中遍历艺术家的方法。
一种从现有艺术家属性生成样式表的机制。这对于允许用户从现有图形(可能已使用 matplotlib API 设置外观)导出样式表很有用...
实施#
如果将“样式”创建为单独的类并将艺术家作为属性存储,则允许“第 3 方”修改/设置艺术家的风格将是最容易的。该类GraphicsContextBase
已经提供了类的基础,
并且可以重构Style
艺术家的方法以使用该类,而不是设置自己的类并将其与样式相关的属性传递给它。此处显示了如何实现此功能的最小示例:https ://github.com/JamesRamm/mpl_experimentdraw
Style
GraphicsContextBase
IMO,这也将使 API 和代码库更加整洁,因为艺术家风格属性的单个 get/set 方法现在是多余的……间接相关的是用属性替换 get/set 方法的一般驱动。使用属性实现样式类将是朝着这个方向迈出的一大步……
对于初始开发,我建议开发一种基于非常(非常)简化的 CSS 版本的语法。我赞成为这个艺术家样式表配音 :+1: :
BNF 语法#
我提出了一个非常简单的语法来最初实现(如概念证明),将来可以扩展。下面给出语法的 BNF 形式,然后解释
RuleSet ::= SelectorSequence "{"Declaration"}"
SelectorSequence :: = Selector {"," Selector}
Declaration ::= propName":" propValue";"
Selector ::= ArtistIdent{"#"Ident}
propName ::= Ident
propValue ::= Ident | Number | Colour | "None"
ArtistIdent
、Ident
和是由正则表达式定义的标记(表达式的基本构建块)Number
。Colour
语法#
CSS 样式表由一系列按层次顺序排列的规则集组成(规则从上到下应用)。每个规则都遵循语法
selector {attribute: value;}
每个规则可以有任意数量的对,样式表可以有任意数量的规则。attribute: value
初始语法仅为Artist
原语设计。它没有解决如何在Container
类型上设置属性的问题(其属性本身可能Artist
是具有可设置属性的 s),但是,未来的解决方案可以简单地嵌套
RuleSet
s
选择器#
选择器定义属性更新应该应用到的对象。作为起点,我建议在初始开发中只使用 2 个选择器:
艺术家类型选择器
Line2D {attribute: value}
匹配艺术家类型选择器(ArtistIdent
在 BNF 语法中)的正则表达式将是:
ArtistIdent = r'(?P<ArtistIdent>\bLine2D\b|\bText\b|\bAxesImage\b|\bFigureImage\b|\bPatch\b)'
GID 选择器#
Artist
按其选择一个gid
:
Line2D#myGID {attribute: value}
Agid
可以是任何字符串,所以正则表达式可以如下:
Ident = r'(?P<Ident>[a-zA-Z_][a-zA-Z_0-9]*)'
上述选择器大致对应于它们的 CSS 对应物(http://www.w3.org/TR/CSS21/selector.html)
属性和值#
Attributes
是相关问题的任何有效(可设置)属性Artist
。Values
是属性的任何有效值(通常是字符串或数字)。
解析#
解析将包括将样式表分解为标记(python 食谱在第 66 页提供了一个很好的标记化配方),应用语法规则并构造一个Tree
. 这需要定义样式表的语法(同样,我们可以借鉴 CSS)并编写解析器。令人高兴的是,python 食谱中也有这个食谱。
matplotlib 图的访问者模式#
为了将样式表规则应用于相关艺术家,我们需要“访问”图中的每个艺术家并应用相关规则。这是一个访问者类(再次感谢 python 食谱),其中每个
node
人都是图中的艺术家。visit_
需要为每个 mpl 艺术家实现一个方法,以处理每个 mpl 艺术家的不同属性
class Visitor:
def visit(self, node):
name = 'visit_' + type(node).__name__
meth = getattr(self, name, None)
if meth is None:
raise NotImplementedError
return meth(node)
然后一个evaluator
类将采用样式表规则并在每个规则上实现访问者。
向后兼容性#
实现一个单独的Style
类会破坏向后兼容性,因为艺术家上的许多 get/set 方法将变得多余。虽然可以更改这些方法以挂接到Style
类中(存储为针对艺术家的属性),但我赞成简单地删除它们以整理/简化代码库并提供简单、整洁的 API。 .
替代方案#
没有其他选择,但这里涵盖的一些领域与 MEP25 重叠,这可能有助于这一发展
附录#
Matplotlib 原语#
这将形成样式表可以使用的初始选择器。
线2D
文本
轴图像
图图像
修补