Диаграмма рассеяния Pyplot с использованием facecolors = 'none' и сохранением краевых цветов по умолчанию для детерминированного выбора цвета маркера - PullRequest
1 голос
/ 29 апреля 2019

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

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9,10])
plt.scatter(x, x**2, s=50, marker='s',facecolors='none')
plt.scatter(x, x**3, s=50, marker='s',facecolors='none')
plt.scatter(x, x**4, s=50, marker='s',facecolors='none')

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

plt.scatter(x, x**2, s=50, marker='s',facecolors='none',edgecolors='r')
plt.scatter(x, x**3, s=50, marker='s',facecolors='none',edgecolors='g')
plt.scatter(x, x**4, s=50, marker='s',facecolors='none',edgecolors='b')

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

plt.scatter(x, y, s=50, marker='s',facecolors='none',edgecolor=np.random.rand(3,))

, как я видел, ответил на это SO, но это не идеально, так как я надеюсь иметь детерминированные цвета между прогонами.Так, например, если у меня есть 3 массива, то первый построенный массив всегда имеет цвет 'x', второй всегда цвет 'y', а третий всегда цвет 'z'.Расширяя это до n массивов, построенный массив nth также всегда будет одного цвета (где n может быть очень большим).

Например, если мы рассмотрим простой график с использованием закрашенных цветовмы видим, что первые 3 графика всегда одинакового цвета (синий, оранжевый, зеленый), и даже при добавлении 4-го графика первые 3 графика сохраняют свои исходные цвета.

3 графика,со стандартными цветами пиплота

4 графика, при этом исходные 3 графика сохраняют свои исходные цвета, как на первом изображении выше

РЕДАКТИРОВАТЬ:Кто-нибудь знает причину отсутствия edgefaces (что позволило бы нам легко использовать цвета пиплота по умолчанию) при установке facecolors='none'?Это кажется довольно странным выбором дизайна.

Ответы [ 2 ]

1 голос
/ 29 апреля 2019

Вы можете создать цветовую карту в matplotlib, а затем включить ее в итерацию по серии.

import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9,10])
powers = [2, 3, 4]

# create a list of 5 colors from viridis, we only use the last 3, but there are 
# 5 in the colormap
colors = cm.get_cmap('viridis', 5)

for c, p in zip(colors(powers), powers):
    plt.scatter(x, x**p, s=50, marker='s',facecolors='none', edgecolor=c)

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

0 голосов
/ 29 апреля 2019

Две вещи, чтобы отметить заранее

  1. Вы хотите иметь n разных цветов, где n априори неизвестно.Цветовой цикл по умолчанию в Matplotlib имеет 10 цветов.Поэтому, если есть вероятность, что n станет больше 10, предпосылка не определять цвета самостоятельно нарушается.Затем вам нужно будет либо выбрать пользовательский цветовой цикл, либо определить цвета и в любом случае закрасить их.

  2. Разброс в основном полезен, если вы хотите иметь маркеры разного цвета или размера.Если вместо этого все маркеры должны быть одного цвета, можно легко использовать plot.

Следовательно, кажется,

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9,10])
plt.plot(x, x**2, ls='none', ms=7, marker='s', mfc='none')
plt.plot(x, x**3, ls='none', ms=7, marker='s', mfc='none')
plt.plot(x, x**4, ls='none', ms=7, marker='s', mfc='none')

plt.show()

действительно сделает то, что вынужно, если у вас есть менее 11 графиков.

enter image description here

Если вы действительно хотите использовать точечный график, вы можете использовать маркеркоторый состоит только из контура квадрата, например, marker="$\u25A1$", аналогично , этот ответ ,

import matplotlib.pyplot as plt
import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9,10])

plt.scatter(x, x**2, s=50, marker="$\u25A1$") 
plt.scatter(x, x**3, s=50, marker="$\u25A1$")
plt.scatter(x, x**4, s=50, marker="$\u25A1$")

plt.show()

enter image description here

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