在 Matplotlib 重置颜色循环

假设我有3种交易策略的数据,每种都有交易成本和没有交易成本。我想在相同的轴上绘制6种变量(3种策略 * 2种交易成本)的时间序列。我希望用 alpha=1linewidth=1绘制“有交易成本”线,而用 alpha=0.25linewidth=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()

什么是适当的代码放在指示行重置颜色周期,使它是“回到开始”时,第二个循环被调用?

44946 次浏览

只需选择您的颜色,并将它们分配给一个列表,然后当您绘制您的数据在包含您的列和您希望的颜色的 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 创建一个列表,该列表聚合每个列表中的元素。这允许您同时轻松地对两者进行迭代。

既然你提到你使用海运,我建议你这样做:

with sns.color_palette(n_colors=3):


ax.plot(...)
ax.plot(...)

这将设置调色板使用当前活动的颜色周期,但只有前三个颜色从它。这也是一个通用的解决方案,任何时候你想设置一个临时的颜色周期。

请注意,实际上需要位于 with块之下的唯一事情是创建 Axes对象(即 plt.subplotsfig.add_subplot()等)所需的任何操作。这只是因为 matplotlib 颜色循环本身是如何工作的。

做你特别想要的,“重置”颜色循环,是可能的,但这是一个黑客,我不会这样做,在任何种类的生产代码。不过,这种情况可能是这样发生的:

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)

enter image description here

你可以用 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,其中 Nothing 作为唯一的参数,并且它将被 rcParams [‘ axes.color _ cle’]中的默认循环所替换。

我用下面的代码尝试了一下,得到了预期的结果:

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()

Code output, showing the color cycling reset functionality

你可以从海运得到这样的颜色: colors = sns.color_palette()。那么 Ffisegydd 的回答将非常有效。您还可以使用模/余数运算符(%) : mycolor = colors[icolumn % len(colors]获得绘图所需的颜色。我自己经常使用这种方法。所以你可以这样做:

对于 icol,枚举中的列(with _ action _ frame. column) : 我的颜色 = 颜色[ icol% len (颜色)] Plot (with _ action _ frame [ col] ,label = colα = 1.0,color = mycolor)

不过,菲舍吉德的回答可能更为“蟒蛇式”。

由于@pelson 给出的答案使用 set_color_cycle,而 Matplotlib 1.5不推荐使用 set_color_cycle,因此我认为使用 set_prop_cycle更新他的解决方案会很有用:

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()

还要注意,我必须把 np.arange(10,1,-1)改成 np.arange(10,0,-1)。前者给出的数组只有9个元素。这可能是因为使用了不同的 Numpy 版本。我的是1.10.2。

编辑 : 不需要使用 rcParams。感谢@divenex 在评论中指出这一点。

除了已经很棒的答案之外,你可以考虑使用颜色图:

import matplotlib.pyplot as plt
import numpy as np


cmap = plt.cm.viridis


datarange = np.arange(4)


for d in datarange:
# generate colour by feeding float between 0 and 1 to colormap
color = cmap(d/np.max(datarange))
plt.plot(np.arange(5)+d, c=color)


for d in datarange:
# generate colour by feeding float between 0 and 1 to colormap
color = cmap(d/np.max(datarange))
plt.plot(-np.arange(5)+d, c=color)

enter image description here