Подтвердить что ты не робот

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 цикл цвета, чтобы он возвращался к началу при вызове второго цикла?

4b9b3361

Ответ 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".