Установка разного цвета для каждой серии в поле рассеяния на matplotlib - программирование
Подтвердить что ты не робот

Установка разного цвета для каждой серии в поле рассеяния на matplotlib

Предположим, что у меня есть три набора данных:

X = [1,2,3,4]
Y1 = [4,8,12,16]
Y2 = [1,4,9,16]

Я могу разбить график следующим образом:

from matplotlib import pyplot as plt
plt.scatter(X,Y1,color='red')
plt.scatter(X,Y2,color='blue')
plt.show()

Как я могу сделать это с помощью 10 наборов?

Я искал это и мог найти любую ссылку на то, что я прошу.

Изменить: уточнить (надеюсь) мой вопрос

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

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

4b9b3361

Ответ 1

Я не знаю, что вы подразумеваете под "вручную". Вы можете выбрать colourmap и сделать цветовой массив достаточно легко:

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

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]

colors = cm.rainbow(np.linspace(0, 1, len(ys)))
for y, c in zip(ys, colors):
    plt.scatter(x, y, color=c)

или сделайте свой собственный цветовой цикл с помощью itertools.cycle и указав цвета, которые вы хотите перебрать, используя next, чтобы получить тот, который вы хотите. Например (я слишком ленив, чтобы напечатать десять цветов):

colors = itertools.cycle(["r", "b", "g"])
for y in ys:
    plt.scatter(x, y, color=next(colors))

Подумайте об этом, возможно, чище не использовать zip с первым:

colors = iter(cm.rainbow(np.linspace(0, 1, len(ys))))
for y in ys:
    plt.scatter(x, y, color=next(colors))

[PS: Я действительно ненавижу, что мне нужно сбросить "u" при работе с matplotlib..]

Ответ 2

Обычный способ построения графиков с точками в разных цветах в matplotlib - это передать список цветов в качестве параметра.

например:.

import matplotlib.pyplot
matplotlib.pyplot.scatter([1,2,3],[4,5,6],color=['red','green','blue'])

3 цвета

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

Но если по какой-то причине вы хотели сделать это всего за один вызов, вы можете сделать большой список цветов, со списком и небольшим разделением полов:

import matplotlib
import numpy as np

X = [1,2,3,4]
Ys = np.array([[4,8,12,16],
      [1,4,9,16],
      [17, 10, 13, 18],
      [9, 10, 18, 11],
      [4, 15, 17, 6],
      [7, 10, 8, 7],
      [9, 0, 10, 11],
      [14, 1, 15, 5],
      [8, 15, 9, 14],
       [20, 7, 1, 5]])
nCols = len(X)  
nRows = Ys.shape[0]

colors = matplotlib.cm.rainbow(np.linspace(0, 1, len(Ys)))

cs = [colors[i//len(X)] for i in range(len(Ys)*len(X))] #could be done with numpy repmat
Xs=X*nRows #use list multiplication for repetition
matplotlib.pyplot.scatter(Xs,Ys.flatten(),color=cs)

Все построенные

cs = [array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.5,  0. ,  1. ,  1. ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 array([ 0.28039216,  0.33815827,  0.98516223,  1.        ]),
 ...
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00]),
 array([  1.00000000e+00,   1.22464680e-16,   6.12323400e-17,
          1.00000000e+00])]

Ответ 3

Легкое исправление

Если у вас есть только один тип коллекций (например, разброс без баров ошибок), вы также можете изменить цвета после того, как вы их построили, иногда это проще выполнить.

import matplotlib.pyplot as plt
from random import randint
import numpy as np

#Let generate some random X, Y data X = [ [frst group],[second group] ...]
X = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)]
Y = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)]
labels = range(1,len(X)+1)

fig = plt.figure()
ax = fig.add_subplot(111)
for x,y,lab in zip(X,Y,labels):
        ax.scatter(x,y,label=lab)

Единственный фрагмент кода, который вам нужен:

#Now this is actually the code that you need, an easy fix your colors just cut and paste not you need ax.
colormap = plt.cm.gist_ncar #nipy_spectral, Set1,Paired  
colorst = [colormap(i) for i in np.linspace(0, 0.9,len(ax.collections))]       
for t,j1 in enumerate(ax.collections):
    j1.set_color(colorst[t])


ax.legend(fontsize='small')

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

enter image description here

Ответ 4

Этот вопрос немного сложнее до января 2013 года и matplotlib 1.3.1 (август 2013 года), который является самой старой стабильной версией, которую вы можете найти на веб-сайте matpplotlib. Но после этого это довольно тривиально.

Поскольку существующая версия поддержки matplotlib.pylab.scatter, которая назначает: массив строки имени цвета, массив числа с плавающей точкой с цветовой картой, массив RGB или RGBA.

этот ответ посвящен бесконечной страсти @Oxinabox к исправлению версии 2013 года для себя в 2015 году.


у вас есть два варианта использования команды рассеяния с несколькими цветами в одном вызове.

  • as pylab.scatter поддержка команд использует RGBA-массив для выполнения любого цвета, который вы хотите;

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

код также вдохновлен исходным кодом pyplot.scatter, я просто дублировал то, что разбрасывает, без запуска его рисования.

команда pyplot.scatter возвращает объект PatchCollection в файле "matplotlib/collections.py" приватную переменную _facecolors в классе Collection и метод set_facecolors.

поэтому всякий раз, когда у вас есть точки разброса, вы можете сделать это:

# rgbaArr is a N*4 array of float numbers you know what I mean
# X is a N*2 array of coordinates
# axx is the axes object that current draw, you get it from
# axx = fig.gca()

# also import these, to recreate the within env of scatter command 
import matplotlib.markers as mmarkers
import matplotlib.transforms as mtransforms
from matplotlib.collections import PatchCollection
import matplotlib.markers as mmarkers
import matplotlib.patches as mpatches


# define this function
# m is a string of scatter marker, it could be 'o', 's' etc..
# s is the size of the point, use 1.0
# dpi, get it from axx.figure.dpi
def addPatch_point(m, s, dpi):
    marker_obj = mmarkers.MarkerStyle(m)
    path = marker_obj.get_path()
    trans = mtransforms.Affine2D().scale(np.sqrt(s*5)*dpi/72.0)
    ptch = mpatches.PathPatch(path, fill = True, transform = trans)
    return ptch

patches = []
# markerArr is an array of maker string, ['o', 's'. 'o'...]
# sizeArr is an array of size float, [1.0, 1.0. 0.5...]

for m, s in zip(markerArr, sizeArr):
    patches.append(addPatch_point(m, s, axx.figure.dpi))

pclt = PatchCollection(
                patches,
                offsets = zip(X[:,0], X[:,1]),
                transOffset = axx.transData)

pclt.set_transform(mtransforms.IdentityTransform())
pclt.set_edgecolors('none') # it up to you
pclt._facecolors = rgbaArr

# in the end, when you decide to draw
axx.add_collection(pclt)
# and call axx parent to draw_idle()

Ответ 5

Вы всегда можете использовать функцию plot() следующим образом:

import matplotlib.pyplot as plt

import numpy as np

x = np.arange(10)
ys = [i+x+(i*x)**2 for i in range(10)]
plt.figure()
for y in ys:
    plt.plot(x, y, 'o')
plt.show()

plot as scatter but changes colors

Ответ 6

Это работает для меня:

для каждой серии используйте случайный генератор цветов rgb

c = color[np.random.random_sample(), np.random.random_sample(), np.random.random_sample()]