【发布时间】:2020-09-06 02:00:00
【问题描述】:
有人能向我解释一下这个特定的例子是如何工作的吗,取自 matplotlib documentation 在 Persistent Cycles 部分下?
基本上他们创建了颜色循环器,我不确定它们是工厂函数还是迭代器,还是普通函数或对象。不知何故,您可以使用有限的iter(my_cycler) 和使用my_cycler() 的 itertools.cycle 生成器来制作生成器。这是如何工作的。
所以我的问题是:为什么你可以做iter(my_cycler),它给出了有限的东西,为什么你可以做my_cycler(),它给出了同样的东西,但它是无限的(它循环)。
>>> from cycler import cycler
>>> cyl = cycler(color=['r', 'g', 'b'])
>>> type(cyl)
cycler.Cycler
>>> import cycler
>>> cycler.Cycler.__mro__
(cycler.Cycler, object)
>>> type(cyl())
itertools.cycle
>> type(iter(cyl))
generator
当我输入时:
>>> next(cyl)
TypeError: 'Cycler' object is not an iterator
但不知何故,这在这里有效:
>>> for s in cyl:
... print(s)
{'color': 'r'}
{'color': 'g'}
{'color': 'b'}
另一个问题是defaultdict的奇怪应用。 styles = defaultdict(lambda : next(finite_cy_iter))。我想我大致了解它,但我想确定:每次密钥不在字典中时,都会调用 (lambda : next(finite_cy_iter))() 或其他东西。根据关于 defaultdicts 的文档,你必须给它一个函数,在这种情况下是function = (lambda : next(finite_cy_iter))。所以我猜每次一个键不在字典中时 function 被调用,这实际上是一个伪装的迭代器,它为您提供循环器中的下一个字典,然后将其存储为该键的值。
这是 matplotlib 文档中的部分:
持续循环 通过字典查找将给定标签与样式相关联并动态生成该映射可能很有用。这可以使用 defaultdict 轻松完成
In [40]: from cycler import cycler as cy
In [41]: from collections import defaultdict
In [42]: cyl = cy('c', 'rgb') + cy('lw', range(1, 4))
获得一组有限的样式
In [43]: finite_cy_iter = iter(cyl)
In [44]: dd_finite = defaultdict(lambda : next(finite_cy_iter))
or repeating
In [45]: loop_cy_iter = cyl()
In [46]: dd_loop = defaultdict(lambda : next(loop_cy_iter))
这在绘制同时具有分类和标签的复杂数据时会很有帮助
finite_cy_iter = iter(cyl)
styles = defaultdict(lambda : next(finite_cy_iter))
for group, label, data in DataSet:
ax.plot(data, label=label, **styles[group])
这将导致同一组的每个数据都以相同的样式绘制。
【问题讨论】:
-
休闲读者,请理解 OP 声明“基本上他们创建颜色循环仪”具有误导性፨ ፨
cycler对象可以在每次迭代时提供不同 Artist 属性的字典(例如,对于 Line2D,您不仅可以指定颜色,还可以指定线宽、线型、标记形状等),以便在不幸的情况下询问您在同一张图上绘制数十条不同的曲线(除了你的老板,没有人会想要这样一团糟;-),每条曲线都具有使其独特的视觉特征。 -
对不起,你是对的。我的意思是说一般来说线属性循环器。我认为最常见的用例,尤其是对我来说,是以特定的、更合乎逻辑的顺序制作颜色(例如,在一个图中显示一天一天的进展)。
标签: python matplotlib colors iterator