重置Matplotlib中的颜色循环
假设我有3种交易策略的数据,每种都有或没有交易成本。 我想在相同的轴上绘制6个变量中的每个变量的时间序列(3个策略* 2个交易成本)。 我希望用alpha=1和linewidth=1绘制“有交易成本”线,而我想用alpha=0.25和linewidth=5绘制“无交易成本”线。但是我希望每种策略的两个版本的颜色都相同 。
我想要一些类似的东西:
fig, ax = plt.subplots(1, 1, figsize=(10, 10))
for c in with_transaction_frame.columns:
ax.plot(with_transaction_frame[c], label=c, alpha=1, linewidth=1)
****SOME MAGIC GOES HERE TO RESET THE COLOR CYCLE
for c in no_transaction_frame.columns:
ax.plot(no_transaction_frame[c], label=c, alpha=0.25, linewidth=5)
ax.legend()
在指定的行上放上什么代码以重置颜色循环,以便在调用第二个循环时“回到起点”,该怎么做?
5个解决方案
65 votes
您可以使用Axes.set_color_cycle将颜色循环重置为原始颜色循环。 查看此代码,有一个函数可以完成实际工作:
def set_color_cycle(self, clist=None):
if clist is None:
clist = rcParams['axes.color_cycle']
self.color_cycle = itertools.cycle(clist
在轴上使用它的方法:
def set_color_cycle(self, clist):
"""
Set the color cycle for any future plot commands on this Axes.
*clist* is a list of mpl color specifiers.
"""
self._get_lines.set_color_cycle(clist)
self._get_patches_for_fill.set_color_cycle(clist)
这基本上意味着您可以调用set_color_cycle,并且将None作为唯一参数,并将其替换为rcParams ['axes.color_cycle']中的默认循环。
我使用以下代码尝试了此操作,并获得了预期的结果:
import matplotlib.pyplot as plt
import numpy as np
for i in range(3):
plt.plot(np.arange(10) + i)
# for Matplotlib version < 1.5
plt.gca().set_color_cycle(None)
# for Matplotlib version >= 1.5
plt.gca().set_prop_cycle(None)
for i in range(3):
plt.plot(np.arange(10, 1, -1) + i)
plt.show()
pelson answered 2020-02-16T13:46:48Z
23 votes
由于@pelson给出的答案使用了set_color_cycle,而Matplotlib 1.5中已弃用了这一点,我认为使用rcParams来更新其解决方案的版本将非常有用:
import matplotlib.pyplot as plt
import numpy as np
for i in range(3):
plt.plot(np.arange(10) + i)
plt.gca().set_prop_cycle(None)
for i in range(3):
plt.plot(np.arange(10, 0, -1) + i)
plt.show()
还请注意,我必须将rcParams更改为np.arange(10,0,-1)。前者仅包含9个元素。 这可能是由于使用了不同的Numpy版本而引起的。 我的是1.10.2。
编辑:删除了使用rcParams的需要。感谢@divenex在注释中指出了这一点。
Ramon Crehuet answered 2020-02-16T13:47:18Z
5 votes
既然您提到您正在使用seaborn,那么我建议您做的是:
with sns.color_palette(n_colors=3):
ax.plot(...)
ax.plot(...)
这会将调色板设置为使用当前活动的颜色周期,但仅使用其中的前三种颜色。 对于您要设置临时颜色周期的任何时间,它也是一种通用解决方案。
请注意,实际上唯一需要放在with块下的就是创建Axes对象(即plt.subplots、fig.add_subplot()等)所做的一切。 这仅仅是因为matplotlib颜色循环本身是如何工作的。
可以执行您特别想要的操作,以“重置”颜色循环,但这是一个hack,我不会在任何一种生产代码中使用。 但是,这是如何发生的:
f, ax = plt.subplots()
ax.plot(np.random.randn(10, 3))
ax._get_lines.color_cycle = itertools.cycle(sns.color_palette())
ax.plot(np.random.randn(10, 3), lw=5, alpha=.25)
mwaskom answered 2020-02-16T13:47:54Z
2 votes
您可以像这样从seaborn获得颜色:for icol, column in enumerate(with_transaction_frame.columns):
mycolor = colors[icol % len(colors]
ax.plot(with_transaction_frame[col], label=col, alpha=1.0, color=mycolor)。Ffisegydd的回答将非常有用。 您还可以使用模数/余数运算符(%)来绘制颜色:mycolor = colors[icolumn % len(colors]。我自己经常使用这种方法。 因此,您可以执行以下操作:
for icol, column in enumerate(with_transaction_frame.columns):
mycolor = colors[icol % len(colors]
ax.plot(with_transaction_frame[col], label=col, alpha=1.0, color=mycolor)
不过,Ffisegydd的答案可能更像“蟒蛇”。
Brad Campbell answered 2020-02-16T13:48:23Z
2 votes
只需选择您的颜色并将其分配给列表,然后在绘制数据时,在包含您的列和所需颜色的zip对象上进行迭代。
colors = ['red', 'blue', 'green']
for col, color in zip(colors, with_transaction_frame.columns):
ax.plot(with_transaction_frame[col], label=col, alpha=1.0, linewidth=1.0, color=color)
for col, color in zip(no_transaction_frame.columns):
ax.plot(no_transaction_frame[col], label=col, alpha=0.25, linewidth=5, color=color)
zip创建一个列表,该列表汇总每个列表中的元素。 这使您可以同时轻松地遍历两个对象。
Ffisegydd answered 2020-02-16T13:48:48Z