Почему matplotlib окрашивает мой сюжет так много цветов? - PullRequest
0 голосов
/ 02 ноября 2018

Я строю несколько объектов, оба из которых состоят из нескольких прямых линий. Для этого я использую список цветов и назначаю один для каждого объекта. Желаемый результат выглядит так: two colors
Я делаю это с помощью команды plt.plot, предоставляющей начальную и конечную точку и цвет.

Пытаясь получить этот результат, я допустил ошибку, и вместо имен, таких как 'pink', я указал значения, такие как (0, 0.75, 0).
Что привело к этому:
many colors

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

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

То же самое происходит, когда я передаю False вместо цвета.


MCVE

import matplotlib.pyplot as plt

# Line in black
plt.plot([-1,-1], [-1,1], 'k')
# Line in bad color
plt.plot([0,0],[-1,1], False)
# Line in same bad color
plt.plot([1,1],[-1,1], False)
# Line in other bad color
plt.plot([2,2],[-1,1], (0,0.75,0))
# Line in same other bad color
plt.plot([3,3],[-1,1], (0,0.75,0))
plt.show()

MCVE Result Image


Примечание:
Я не ищу, как получить желаемый результат, передавая постоянный цвет. Мне это удалось. Но по дороге я столкнулся с таким поведением, которое хотел бы понять.
Основываясь на комментариях, кажется вероятным, что в pyplot есть некоторая документированная и хорошо известная функциональность, которая просто использует цветовой цикл и берет следующий цвет в нем, когда не предоставлен действительный цвет. Однако я не могу найти документацию по этому вопросу, поэтому мне хотелось бы либо цитаты из документации, либо ответа, что это недокументированное поведение, или что-то в этом роде.

Стоит также отметить, что что-то в середине изображения также было нарисовано, когда я использовал недопустимые параметры цвета, но не при использовании правильных значений. Почему?

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

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

В документации указаны следующие способы вызова этой функции.

plot([x], y, [fmt], data=None, **kwargs)
plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)

Аргументы в квадратных скобках являются необязательными, а эллипсы обозначают произвольное число следующих передаваемых аргументов.

Рассматривая приведенные выше случаи и переименовывая соответствующие аргументы:

1

plt.plot([-1,-1], [-1,1], 'k')
plt.plot(   x   ,    y  , fmt)

Как и ожидалось, 'k' - это формат, который будет использоваться.

2

plt.plot([0,0],[-1,1], False)
plt.plot(  x  ,   y  ,   y2 )

Здесь False не является допустимой строкой формата. Следовательно, это интерпретируется как данные для новой строки. Поскольку нет другого следующего аргумента, который можно интерпретировать, он не может быть x2, следовательно, он должен быть y2. False эквивалентно 0. Таким образом, вы получите одну точку в точке (0,0), которую вы не видите на графике, потому что маркер не указан. Если бы вы использовали

plt.plot([0,0],[-1,1], False, "o")

вместо этого вы увидите оранжевую точку.

enter image description here

3.

То же, что и выше. Единственное отличие состоит в том, что вы получаете линию другого цвета в соответствии с используемым цветовым циклом (см. Ниже в этом ответе).

4.

plt.plot([2,2],[-1,1], (0,0.75,0))
plt.plot(  x  ,   y  ,     y2    )

Опять же, третий аргумент не является допустимой строкой формата. Это снова интерпретируется как значения y следующей строки. На этот раз, в отличие от 2. и 3., y2 содержит несколько координат. Поэтому линия вдоль точек (0,0), (1,0.75), (2,0) проведена.

enter image description here


Во всех случаях, кроме первого, цвет не указан. В этом случае в соответствии с документами

По умолчанию каждой строке присваивается свой стиль, указанный в «цикле стилей». Параметры свойств fmt и line необходимы только в том случае, если вы хотите явно отклониться от этих значений по умолчанию. Кроме того, вы также можете изменить цикл стиля, используя 'axes.prop_cycle' rcParam.

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

Вы можете распечатать цикл по умолчанию

print(plt.rcParams["axes.prop_cycle"])

# cycler('color', ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b',
#                   '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'])

Или вы можете установить его

plt.rcParams["axes.prop_cycle"] = plt.cycler("color", ["red", "#001eff", (0, 0.75, 0)])

Пример доступен на странице matplotlib: Стилизация с помощью cycler , а также Цвета в цикле свойств по умолчанию

cycler также имеет свою собственную страницу документации, https://matplotlib.org/cycler/, поскольку она может в равной степени использоваться для других целей, кроме matplotlib.

Возвращаясь к началу вопроса; для того чтобы все линии были одинакового цвета, можно установить цветовой цикл на один цвет

plt.rcParams["axes.prop_cycle"] = plt.cycler("color", ["k"])

В этом случае все линии на осях будут выглядеть черными.

0 голосов
/ 02 ноября 2018

Не видя код, трудно ответить, Но вы можете попробовать назначить цвет явно? Более того, вы не можете сделать plt.plot(x,y,color), вам нужно написать имя параметра явно, как это plt.plot(x,y,c = color) или plt.plot(x,y,color = color)

Вы можете попробовать этот код:

import matplotlib.pyplot as plt


blue = (0,0,0.75)
green = (0, 0.75, 0)
# Line in black
plt.plot([-1,-1], [-1,1], color = blue)
# Line in bad color
plt.plot([0,0],[-1,1] , color = blue)
# Line in same bad color
plt.plot([1,1],[-1,1], color = blue)
# Line in other bad color
plt.plot([2,2],[-1,1], color = green)
# Line in same other bad color
plt.plot([3,3],[-1,1], color = green)
plt.show()

enter image description here

И причина, по которой вы можете использовать plt.plot([3,3],[-1,1], "green") вместо plt.plot([3,3],[-1,1], green), взята из документации по сюжету .

Третьим параметром по умолчанию является fmt, и его определение: Строка формата состоит из части для цвета, маркера и линии: fmt = '[color] [marker] [line]'. Я думаю, что функция plot будет работать правильно, если она распознает, что третий параметр является принятой строкой.

Вместо подачи '(0, 0,75, 0)', чем "green", функция будет обрабатывать '(0, 0,75, 0)' как линейный сегмент x = (0, 1, 2) y =(0, 0.75, 0), поэтому существует дополнительная отрезок на вашем участке. И обычно сюжет назначает ему цвет по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...