Reset цветной цикл в 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()
Какой код должен помещать указанную строку в reset цикл цвета, чтобы он возвращался к началу при вызове второго цикла?
Ответы
Ответ 1
Вы можете сбросить цветовой цикл в оригинал с помощью 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()
![Code output, showing the color cycling reset functionality]()
Ответ 2
Как ответ @pelson использует set_color_cycle
, и это устарело в Matplotlib 1.5, я подумал, что было бы полезно иметь обновленную версию его решения, используя 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 за то, что указали это в комментарии.
Ответ 3
Поскольку вы упомянули, что используете морские лодки, я бы рекомендовал сделать это:
with sns.color_palette(n_colors=3):
ax.plot(...)
ax.plot(...)
Это приведет к тому, что цветовая палитра будет использоваться в текущем активном цветовом цикле, но только первые три цвета. Это также универсальное решение в любое время, когда вы хотите установить временной цикл цвета.
Обратите внимание, что единственное, что действительно должно быть в блоке with
, - это то, что вы делаете, чтобы создать объект Axes
(т.е. plt.subplots
, fig.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]()
Ответ 4
Просто выберите цвета и назначьте их списку, затем, когда вы построите свои данные, перейдете к объекту 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
создает список, который объединяет элементы из каждого из ваших списков. Это позволяет одновременно выполнять итерацию одновременно.
Ответ 5
Вы можете получить цвета с морского дерева следующим образом: colors = sns.color_palette()
. Тогда ответ 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 может быть более "pythonic".