Как получить разноцветные линии для разных сюжетов на одной фигуре?

202

Я использую matplotlibдля создания участков. Я должен идентифицировать каждый график с другим цветом, который должен автоматически генерироваться Python.

Не могли бы вы дать мне способ разместить разные цвета на разных графиках на одной фигуре?

pottigopi
источник

Ответы:

424

Matplotlib делает это по умолчанию.

Например:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)
plt.show()

Основной сюжет, демонстрирующий цветовые циклы

И, как вы уже знаете, вы можете легко добавить легенду:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

Основной сюжет с легендой

Если вы хотите контролировать цвета, которые будут циклически проходить:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(10)

plt.gca().set_color_cycle(['red', 'green', 'blue', 'yellow'])

plt.plot(x, x)
plt.plot(x, 2 * x)
plt.plot(x, 3 * x)
plt.plot(x, 4 * x)

plt.legend(['y = x', 'y = 2x', 'y = 3x', 'y = 4x'], loc='upper left')

plt.show()

График, показывающий контроль над цветовым циклом по умолчанию

Если вы не знакомы с matplotlib, учебник - хорошее место для начала .

Редактировать:

Прежде всего, если у вас есть много (> 5) вещей, которые вы хотите построить на одной фигуре, либо:

  1. Разместите их на разных участках (рассмотрите возможность использования нескольких участков на одном рисунке), или
  2. Используйте что-то кроме цвета (то есть стили маркера или толщину линии), чтобы различать их.

В противном случае вы получите очень грязный сюжет! Будьте добры к тому, кто когда-либо прочитает все, что вы делаете, и не пытайтесь втиснуть 15 разных вещей в одну фигуру !!

Кроме того, многие люди в разной степени дальтоники, и различие между многочисленными едва различимыми цветами трудно для большего количества людей, чем вы можете себе представить.

При этом, если вы действительно хотите поместить 20 линий на одну ось с 20 относительно разными цветами, вот один из способов сделать это:

import matplotlib.pyplot as plt
import numpy as np

num_plots = 20

# Have a look at the colormaps here and decide which one you'd like:
# http://matplotlib.org/1.2.1/examples/pylab_examples/show_colormaps.html
colormap = plt.cm.gist_ncar
plt.gca().set_prop_cycle(plt.cycler('color', plt.cm.jet(np.linspace(0, 1, num_plots))))

# Plot several different functions...
x = np.arange(10)
labels = []
for i in range(1, num_plots + 1):
    plt.plot(x, i * x + 5 * i)
    labels.append(r'$y = %ix + %i$' % (i, 5*i))

# I'm basically just demonstrating several different legend options here...
plt.legend(labels, ncol=4, loc='upper center', 
           bbox_to_anchor=[0.5, 1.1], 
           columnspacing=1.0, labelspacing=0.0,
           handletextpad=0.0, handlelength=1.5,
           fancybox=True, shadow=True)

plt.show()

Уникальные цвета для 20 линий на основе заданной карты цветов

Джо Кингтон
источник
17
Обратите внимание, что в последнем примере, в более новых версиях matplotlib, set_color_cycleон не рекомендуется, так что строка должна быть plt.gca().set_prop_cycle(plt.cycler('color', plt.cm.jet(np.linspace(0, 1, num_plots))))и просто изменить в plt.cm.YOUR_PREFERED_COLOR_MAPсоответствии с вашими потребностями.
конец
1
@JoeKington: Объяснение было замечательным, большое спасибо
Рика
это круто. Есть ли способ сделать их интерактивными? например, в RI конвертируйте ggplot в ggplotly (), и сюжет становится html интерактивным
kRazzy R
Я убежден, что ОП знал, что Matplotlib окрашивает соответственно разные кривые на одном графике (на одном axes) и спрашивал об изменении цвета одной линии на разных графиках (разных axes) ... Тем не менее, отличный ответ на важный вопрос (возможно, отличается от того, что задавал ОП, но никто не может сказать, потому что они задали этот единственный вопрос и исчезли!) - +1
gboffi
37

Установка их позже

Если вы не знаете количество графиков, которые вы собираетесь построить, вы можете изменить цвета, как только вы нанесете их на график, получая номер непосредственно из графика, используя это .lines, я использую это решение:

Некоторые случайные данные

import matplotlib.pyplot as plt
import numpy as np

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)


for i in range(1,15):
    ax1.plot(np.array([1,5])*i,label=i)

Кусок кода, который вам нужен:

colormap = plt.cm.gist_ncar #nipy_spectral, Set1,Paired   
colors = [colormap(i) for i in np.linspace(0, 1,len(ax1.lines))]
for i,j in enumerate(ax1.lines):
    j.set_color(colors[i])
  

ax1.legend(loc=2)

Результат следующий:введите описание изображения здесь

GM
источник
8

TL; DR Нет, это не может быть сделано автоматически . Да, это возможно.

import matplotlib.pyplot as plt
my_colors = plt.rcParams['axes.prop_cycle']() # <<< note that we CALL the prop_cycle
fig, axes = plt.subplots(2,3)
for ax in axes.flatten(): ax.plot((0,1), (0,1), **next(my_colors))

введите описание изображения здесь Каждый участок ( axes) на рисунке ( figure) имеет свой собственный цикл цветов - если вы не заставляйте другой цвет для каждого участка, все участки разделяют один и тот же порядок цветов , но, если мы растянуть немного какие «автоматически» средство , это может быть сделано.


ОП написала

[...] Я должен идентифицировать каждый сюжет с другим цветом, который должен автоматически генерироваться [Matplotlib].

Но ... Matplotlib автоматически генерирует разные цвета для каждой кривой

In [10]: import numpy as np
    ...: import matplotlib.pyplot as plt

In [11]: plt.plot((0,1), (0,1), (1,2), (1,0));
Out[11]:

введите описание изображения здесь

Так почему запрос ОП? Если мы продолжим читать, у нас есть

Не могли бы вы дать мне способ разместить разные цвета на разных графиках на одной фигуре?

и это имеет смысл, потому что каждый сюжет (каждый axesна языке Matplotlib) имеет свой собственный color_cycle(точнее, в 2018 году prop_cycle) и каждый сюжет ( axes) использует одни и те же цвета в том же порядке.

In [12]: fig, axes = plt.subplots(2,3)

In [13]: for ax in axes.flatten():
    ...:     ax.plot((0,1), (0,1))

введите описание изображения здесь

Если в этом смысл первоначального вопроса, одна из возможностей - явно назвать разные цвета для каждого сюжета.

Если графики (как это часто бывает) генерируются в цикле, мы должны иметь дополнительную переменную цикла, чтобы переопределить цвет, автоматически выбранный Matplotlib.

In [14]: fig, axes = plt.subplots(2,3)

In [15]: for ax, short_color_name in zip(axes.flatten(), 'brgkyc'):
    ...:     ax.plot((0,1), (0,1), short_color_name)

введите описание изображения здесь

Другая возможность состоит в том, чтобы создать объект cycler

from cycler import cycler
my_cycler = cycler('color', ['k', 'r']) * cycler('linewidth', [1., 1.5, 2.])
actual_cycler = my_cycler()

fig, axes = plt.subplots(2,3)
for ax in axes.flat:
    ax.plot((0,1), (0,1), **next(actual_cycler))

введите описание изображения здесь

Обратите внимание, что type(my_cycler)есть, cycler.Cyclerно type(actual_cycler)есть itertools.cycle.

gboffi
источник
3

Я хотел бы предложить небольшое улучшение в последнем цикле ответа, приведенного в предыдущем посте (этот пост является правильным и все еще должен быть принят). Неявное предположение, сделанное при маркировке последнего примера, заключается в том, что plt.label(LIST)номер метки X вставляется в LISTстроку, соответствующую X-му времени plot. Я столкнулся с проблемами с этим подходом раньше. Рекомендуемый способ создавать легенды и настраивать их метки в соответствии с документацией matplotlibs ( http://matplotlib.org/users/legend_guide.html#adjusting-the-order-of-legend-item ) - иметь теплое ощущение, что метки идут наряду с точными графиками, которые вы думаете, они делают:

...
# Plot several different functions...
labels = []
plotHandles = []
for i in range(1, num_plots + 1):
    x, = plt.plot(some x vector, some y vector) #need the ',' per ** below
    plotHandles.append(x)
    labels.append(some label)
plt.legend(plotHandles, labels, 'upper left',ncol=1)

**: Легенды Matplotlib не работают

Томми
источник
3
Просто к вашему сведению: вы также можете использовать «ярлык» kwarg для построения, а затем вызывать легенду без каких-либо аргументов.
Джо Кингтон