matplotlib
的依赖包cycler
是matplotlib
自主开发的属性组合包,功能与内置模块itertools
很多函数非常相似,可用于创建特殊的迭代器。matpoltlib
在属性设置底层中使用了cycler
包,典型的案例就是在多数据系列绘图中循环使用颜色、线条等外观设置。使用cycler
可以避免构造多重循环,更简便、灵活的组合属性。
cycler
包概述
cycler
包的API主要有三个:
-
cycler(*args, **kwargs)
:工厂函数,创建一个Cycler
对象。cycler(*args, **kwargs)
有三种调用方式:cycler(arg)
:arg
为Cycler
对象。复制Cycler
对象的构造函数。cycler(label1=iter1[, label2=iter2[, ...]])
:label
必须是有效的Python标识符,要求类似字典的键,iter
为可迭代对象。求多组参数的点积,功能类似于zip()
函数。cycler(label, itr)
:从一对label和可迭代对象构造Cycler
对象。这里label
可以为整数和带空格的字符串。
-
Cycler(left[, right, op])
:底层类。 -
concat(left, right)
:拼接两个cycler
对象。
基本功能
cycler
的基本功能是方便的将一个可哈希的对象(hashable
)与一系列值进行映射。
根据下面的例子可知,cycler
对象可以将关键字参数名称与序列进行一一映射,cycler
对象是一个迭代器,迭代输出的对象为字典结构,键为关键字参数名称,值为序列的元素。
In [1]: from cycler import cycler
In [2]: color_cycle = cycler(color=['r', 'g', 'b'])
In [3]: color_cycle
Out[3]: cycler('color', ['r', 'g', 'b'])
In [4]: len(color_cycle)
Out[4]: 3
In [5]: color_cycle.keys
Out[5]: {'color'}
In [6]: for i in color_cycle:
...: print(i)
...:
{'color': 'r'}
{'color': 'g'}
{'color': 'b'}
cycler
的基本功能与循环非常相似,cycler
的强大在于创建复杂的属性组合。
加法运算(cycler
对象相加)
两个cycler
对象进行加法运算,相当于将两个对象的元素按次序一一组合,功能类似于Python内置的zip()
函数。
In [1]: from cycler import cycler
In [2]: color_cycle = cycler(color=['r', 'g', 'b'])
In [3]: lw_cycle = cycler(lw=range(1, 4))
In [4]: wc = lw_cycle + color_cycle
In [5]: for s in wc:
...: print(s)
...:
{'lw': 1, 'color': 'r'}
{'lw': 2, 'color': 'g'}
{'lw': 3, 'color': 'b'}
cycler
函数传递多个关键字参数就相当于对这些参数进行加法运算
In [1]: from cycler import cycler
In [2]: wc = cycler(c=['r', 'g', 'b'], lw=range(3))
In [3]: for s in wc:
...: print(s)
...:
{'c': 'r', 'lw': 0}
{'c': 'g', 'lw': 1}
{'c': 'b', 'lw': 2}
乘法运算(cycler
对象相乘)
两个cycler
对象进行乘法运算,相当于求两个对象的元素的笛卡尔积,功能类似于Python内置的itertools.product()
函数。
In [1]: from cycler import cycler
In [2]: color_cycle = cycler(color=['r', 'g', 'b'])
In [3]: m_cycle = cycler(marker=['s', 'o'])
In [4]: m_c = m_cycle * color_cycle
In [5]: for s in m_c:
...: print(s)
...:
{'marker': 's', 'color': 'r'}
{'marker': 's', 'color': 'g'}
{'marker': 's', 'color': 'b'}
{'marker': 'o', 'color': 'r'}
{'marker': 'o', 'color': 'g'}
{'marker': 'o', 'color': 'b'}
标量乘法运算(cycler
对象与整数相乘)
cycler
对象与整数n
相乘,相当于遍历n
次cycler
对象。
In [1]: from cycler import cycler
In [2]: color_cycle = cycler(color=['r', 'g', 'b'])
In [3]: color_cycle * 2
Out[3]: cycler('color', ['r', 'g', 'b', 'r', 'g', 'b'])
cycler
对象拼接
cycler
对象拼接有一个前提就是两个对象必须有相同的键!
In [1]: from cycler import cycler
In [2]: color_cycle = cycler(color=['r', 'g', 'b'])
In [3]: color_cycle2 = cycler(color=['c', 'm', 'y', 'k'])
In [4]: color_cycle = color_cycle.concat(color_cycle2)
In [5]: color_cycle
Out[6]: cycler('color', ['r', 'g', 'b', 'c', 'm', 'y', 'k'])
In [7]: color_cycle3 = cycler(gray=['0.5'])
In [8]: color_cycle = color_cycle.concat(color_cycle3)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: Keys do not match:
Intersection: set()
Disjoint: {'color', 'gray'}
cycler
对象切片
cycler
对象支持切片操作。
In [1]: from cycler import cycler
In [2]: color_cycle = cycler(color=['r', 'g', 'b'])
In [3]: color_cycle[:2]
Out[3]: cycler('color', ['r', 'g'])
In [4]: color_cycle[::-1]
Out[4]: cycler('color', ['b', 'g', 'r'])
案例:设置线条属性
使用cycler
from cycler import cycler
import matplotlib.pyplot as plt
color_cycle = cycler(color=['r', 'g', 'b'])
m_cycle = cycler(marker=['s', 'o'])
m_c = m_cycle * color_cycle
for i, j in enumerate(m_c):
print(i, j)
plt.plot([i, i], **j)
plt.show()
0 {'marker': 's', 'color': 'r'}
1 {'marker': 's', 'color': 'g'}
2 {'marker': 's', 'color': 'b'}
3 {'marker': 'o', 'color': 'r'}
4 {'marker': 'o', 'color': 'g'}
5 {'marker': 'o', 'color': 'b'}
常规多重循环方法
import matplotlib.pyplot as plt
marker=['s', 'o']
color=['r', 'g', 'b']
n=0
for i in marker:
for j in color:
plt.plot([n, n], marker=i, c=j)
n = n+1
plt.show()
案例总结
相对而言,使用cycler
避免了多重循环,当属性种类较多时更简洁,更加灵活。