MEP26:艺术家造型

状态

Rejected

摘要

这个MEP提出了一个新的样式表实现,允许艺术家进行更全面和动态的样式设计。

Matplotlib(1.4.0)的当前版本允许在创建绘图之前应用基于rcParams语法的样式表。下面的方法提出了一种基于CSS的新语法,它允许对单个艺术家和属性进行样式设置,这些样式可以动态应用于现有对象。

这与(并朝着)移动到类DOM/树架构的总体目标相关。

详细描述

当前,现有艺术家对象(图形、轴、线2d等)的外观和外观只能通过以下方式更新: set_get_ 对艺术家对象的方法,这是非常困难的,特别是如果没有存储对艺术家的引用。1.4中引入的新样式表允许在创建绘图之前进行样式设置,但不提供任何方法来动态更新绘图或区分相同类型的艺术家(即指定 line colorline style 单独用于不同的 Line2D 对象)。

最初的开发应该集中在允许艺术家原语(那些 Artist 不包含其他 Artist s) ,进一步的开发可以扩展CSS语法规则和解析器以允许更复杂的样式。原语列表见附录。

新方法需要制定若干步骤:

  • 一种新的样式表语法(可能基于CSS),允许按类型、类、ID等选择艺术家。
  • 将样式表解析为树的机制
  • 一种将解析树转换为可用于更新相关艺术家属性的内容的机制。理想情况下,这将实现一种方法,通过这种方法可以在树状结构中遍历艺术家。
  • 从现有艺术家属性生成样式表的机制。这将有助于允许用户从现有图形中导出样式表(在该图形中,外观可能是使用matplotlib api设置的)。

实施

如果将“样式”创建为单独的类,并将其作为属性存储,则允许“第三方”修改/设置艺术家的样式最简单。这个 GraphicsContext 类已经提供了 Style 班级和艺术家的 draw 方法可以重构为使用 Style 类而不是设置它自己的类 GraphicsContext 并将其与样式相关的属性传递给它。关于如何实现这一点的一个最小示例如下:https://github.com/jamesramm/mpl_实验

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"

ArtistIdentIdentNumberColour 是由正则表达式定义的标记(表达式的基本构建块)。

句法

CSS样式表由一系列 规则集 按层次顺序(规则从上到下应用)。每个规则遵循以下语法::

selector {attribute: value;}

每个规则可以有任意数量的 attribute: value 对和样式表可以有任意数量的规则。

初始语法仅为 Artist 基元。它没有解决如何设置属性的问题 Container 类型(其属性本身可能是 Artist 但是,未来的解决方案可以简单地嵌套 RuleSet 的S

选择器

选择器定义应用属性更新的对象。作为一个起点,我建议在初始开发中只使用两个选择器:

艺术家类型选择器

选择一个 Artist 按它的类型。例如 Line2DText ::

Line2D {attribute: value}

用于匹配艺术家类型选择器的regex (ArtistIdent 在bnf语法中)应该是:

ArtistIdent = r'(?P<ArtistIdent>\bLine2D\b|\bText\b|\bAxesImage\b|\bFigureImage\b|\bPatch\b)'

GID选择器

选择一个 Artist 由其 gid ::

Line2D#myGID {attribute: value}

A gid 可以是任何字符串,因此regex可以如下所示:

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 . 我们可以借用语法来定义样式表。令人高兴的是,python食谱中也有这样的食谱。

Matplotlib人物的访客模式

为了将样式表规则应用于相关艺术家,我们需要在图形中“访问”每个艺术家并应用相关规则。这是一个访客类(再次感谢python食谱),在这里 node 将是一个艺术家的形象。一 visit_ 需要为每个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
  • 文本
  • AxesImage
  • FigureImage
  • 补丁