mwa*_*kom 84 python matplotlib
是否可以查询matplotlib颜色循环的当前状态?换句话说,是否有一个函数get_cycle_state
将以下列方式运行?
>>> plot(x1, y1)
>>> plot(x2, y2)
>>> state = get_cycle_state()
>>> print state
2
Run Code Online (Sandbox Code Playgroud)
我希望状态是将在绘图中使用的下一个颜色的索引.或者,如果它返回下一个颜色(上例中默认循环的"r"),那也没关系.
Joe*_*ton 99
没有"面向用户"(又称"公共")方法来访问底层迭代器,但您可以通过"私有"(按惯例)方法访问它.但是,如果iterator
不改变它,你就无法获得状态.
快速旁白:您可以通过多种方式设置颜色/属性循环(例如ax.set_color_cycle
,版本<1.5或ax.set_prop_cycler
> = 1.5).请查看此处1.5或更高版本的示例,或此处的上一个样式.
但是,虽然没有面向公共的方法来访问iterable,但您可以ax
通过_get_lines
helper类实例访问给定轴对象(). ax._get_lines
是一个令人困惑的名字,但它是幕后机制,允许plot
命令处理所有plot
可以调用的奇怪和多变的方式.除此之外,它还可以跟踪自动分配的颜色.同样,ax._get_patches_for_fill
可以通过默认填充颜色和补丁属性来控制循环.
无论如何,颜色循环可迭代ax._get_lines.color_cycle
用于线和ax._get_patches_for_fill.color_cycle
补丁.在matplotlib> = 1.5时,这已经改为使用cycler
库,并且调用了iterable prop_cycler
而不是color_cycle
并且生成了一个dict
属性而不是一个颜色.
总而言之,你会做类似的事情:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
color_cycle = ax._get_lines.color_cycle
# or ax._get_lines.prop_cycler on version >= 1.5
# Note that prop_cycler cycles over dicts, so you'll want next(cycle)['color']
Run Code Online (Sandbox Code Playgroud)
iterator
但是,这个对象是"裸露的" iterator
.我们可以很容易地得到下一个项目(例如next_color = next(color_cycle)
,但这意味着之后的下一个颜色将被绘制.通过设计,没有办法获得迭代器的当前状态而不改变它.
在v1.5
或更大,这将是很好得到cycler
多数民众赞成使用,我们可以推断其当前状态的对象.但是,cycler
对象本身无法在任何地方(公开或私下)访问.相反,只能访问itertools.cycle
从cycler
对象创建的实例.无论哪种方式,都无法进入颜色/属性循环器的基础状态.
在你的情况下,听起来你想要匹配刚绘制的东西的颜色.不要试图确定颜色/属性是什么,而是根据绘制内容的属性设置新项目的颜色/等.
例如,在你描述的情况下,我会做这样的事情:
import matplotlib.pyplot as plt
import numpy as np
def custom_plot(x, y, **kwargs):
ax = kwargs.pop('ax', plt.gca())
base_line, = ax.plot(x, y, **kwargs)
ax.fill_between(x, 0.9*y, 1.1*y, facecolor=base_line.get_color(), alpha=0.5)
x = np.linspace(0, 1, 10)
custom_plot(x, x)
custom_plot(x, 2*x)
custom_plot(x, -x, color='yellow', lw=3)
plt.show()
Run Code Online (Sandbox Code Playgroud)
这不是唯一的方法,但它比在此情况下尝试获取绘制线的颜色更清洁.
Mik*_*tis 18
这是一种在1.5中工作的方式,希望能够面向未来,因为它不依赖于下划线前面的方法:
colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
Run Code Online (Sandbox Code Playgroud)
这将为您提供为当前样式定义的颜色列表.
当然,这样做会.
#rainbow
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,2*np.pi)
ax= plt.subplot(1,1,1)
ax.plot(np.sin(x))
ax.plot(np.cos(x))
rainbow = ax._get_lines.color_cycle
print rainbow
for i, color in enumerate(rainbow):
if i<10:
print color,
Run Code Online (Sandbox Code Playgroud)
得到:
<itertools.cycle object at 0x034CB288>
r c m y k b g r c m
Run Code Online (Sandbox Code Playgroud)
这是matplotlib使用itertools.cycle的itertools函数
编辑:感谢您的评论,似乎无法复制迭代器.一个想法是转储一个完整的周期并跟踪你正在使用的值,让我重新开始.
Edit2:好的,这将为您提供下一个颜色,并创建一个新的迭代器,其行为就像下一个未被调用一样.这不保留着色的顺序,只是下一个颜色值,我留给你.
这给出了以下输出,注意图中的陡度对应于索引,例如,第一个g是最底部的图,依此类推.
#rainbow
import matplotlib.pyplot as plt
import numpy as np
import collections
import itertools
x = np.linspace(0,2*np.pi)
ax= plt.subplot(1,1,1)
def create_rainbow():
rainbow = [ax._get_lines.color_cycle.next()]
while True:
nextval = ax._get_lines.color_cycle.next()
if nextval not in rainbow:
rainbow.append(nextval)
else:
return rainbow
def next_color(axis_handle=ax):
rainbow = create_rainbow()
double_rainbow = collections.deque(rainbow)
nextval = ax._get_lines.color_cycle.next()
double_rainbow.rotate(-1)
return nextval, itertools.cycle(double_rainbow)
for i in range(1,10):
nextval, ax._get_lines.color_cycle = next_color(ax)
print "Next color is: ", nextval
ax.plot(i*(x))
plt.savefig("SO_rotate_color.png")
plt.show()
Run Code Online (Sandbox Code Playgroud)
安慰
Next color is: g
Next color is: c
Next color is: y
Next color is: b
Next color is: r
Next color is: m
Next color is: k
Next color is: g
Next color is: c
Run Code Online (Sandbox Code Playgroud)
小智 5
我只想补充上面@Andi 所说的内容。由于color_cycle
在 matplotlib 1.5 中已弃用,因此您必须使用prop_cycler
,但是,Andi 的解决方案 ( ax._get_lines.prop_cycler.next()['color']
) 为我返回了此错误:
AttributeError: 'itertools.cycle' 对象没有属性 'next'
对我next(ax._get_lines.prop_cycler)
有用的代码是:,实际上与@joe-kington 的原始回复相差不远。
就个人而言,我在制作 twinx() 轴时遇到了这个问题,这会重置颜色循环器。我需要一种方法来使颜色正确循环,因为我使用的是style.use('ggplot')
. 可能有更简单/更好的方法来做到这一点,所以请随时纠正我。
归档时间: |
|
查看次数: |
37064 次 |
最近记录: |