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

Как затенять точки разброса на основе цветовой карты в matplotlib?

Я пытаюсь затенять точки в диаграмме рассеяния, основываясь на наборе значений (от 0 до 1), выбранных из одной из уже определенных цветовых карт, таких как Blues или Reds. Я пробовал это:

import matplotlib
import matplotlib.pyplot as plt
from numpy import *
from scipy import *
fig = plt.figure()
mymap = plt.get_cmap("Reds")
x = [8.4808517662594909, 11.749082788323497, 5.9075039082855652, 3.6156231827873615, 12.536817102137768, 11.749082788323497, 5.9075039082855652, 3.6156231827873615, 12.536817102137768]
spaced_colors = linspace(0, 1, 10)
print spaced_colors
plt.scatter(x, x,
            color=spaced_colors,
            cmap=mymap)
# this does not work either
plt.scatter(x, x,
            color=spaced_colors,
            cmap=plt.get_cmap("gray"))

Но это не работает, используя красную или серовую карту цветов. Как это можно сделать?

edit: если я хочу построить каждую точку отдельно, чтобы она могла иметь отдельную легенду, как я могу это сделать? Я пробовал:

fig = plt.figure()
mymap = plt.get_cmap("Reds")
data = np.random.random([10, 2])
colors = list(linspace(0.1, 1, 5)) + list(linspace(0.1, 1, 5))
print "colors: ", colors
plt.subplot(1, 2, 1)
plt.scatter(data[:, 0], data[:, 1],
           c=colors,
           cmap=mymap)
plt.subplot(1, 2, 2)
# attempt to plot first five points in five shades of red,
# with a separate legend for each point
for n in range(5):
    plt.scatter([data[n, 0]], [data[n, 1]],
               c=[colors[n]],
               cmap=mymap,
               label="point %d" %(n))
plt.legend()

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

4b9b3361

Ответ 1

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

import numpy as np
import matplotlib.pyplot as plt 

# plt.subplots instead of plt.subplot
# create a figure and two subplots side by side, they share the
# x and the y-axis
fig, axes = plt.subplots(ncols=2, sharey=True, sharex=True)
data = np.random.random([10, 2]) 
# np.r_ instead of lists
colors = np.r_[np.linspace(0.1, 1, 5), np.linspace(0.1, 1, 5)] 
mymap = plt.get_cmap("Reds")
# get the colors from the color map
my_colors = mymap(colors)
# here you give floats as color to scatter and a color map
# scatter "translates" this
axes[0].scatter(data[:, 0], data[:, 1], s=40,
                c=colors, edgecolors='None',
                cmap=mymap)
for n in range(5):
    # here you give a color to scatter
    axes[1].scatter(data[n, 0], data[n, 1], s=40,
                    color=my_colors[n], edgecolors='None',
                    label="point %d" %(n))
# by default legend would show multiple scatterpoints (as you would normally
# plot multiple points with scatter)
# I reduce the number to one here
plt.legend(scatterpoints=1)
plt.tight_layout()
plt.show()

colored-scatter

Однако, если вы хотите отобразить только 10 значений и хотите назвать каждый из них, вам следует рассмотреть возможность использования чего-то другого, например гистограммы, как в этом example. Другой возможностью было бы использовать plt.plot с пользовательским цветовым циклом, как в этом example.

Ответ 2

В соответствии с документацией вам нужен c аргумент ключевого слова вместо color. (Я согласен, что это немного запутывает, но терминология "c" и "s" наследуется от matlab в этом случае.)

например.

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

x, y, colors = np.random.random((3,10))

fig, ax = plt.subplots()
ax.scatter(x, y, c=colors, s=50, cmap=mpl.cm.Reds)

plt.show()

enter image description here

Ответ 3

Как насчет:

import matplotlib.pyplot as plt
import numpy as np


reds = plt.get_cmap("Reds")
x = np.linspace(0, 10, 10)
y = np.log(x)

# color by value given a cmap
plt.subplot(121)
plt.scatter(x, y, c=x, s=100, cmap=reds)


# color by value, and add a legend for each
plt.subplot(122)
norm = plt.normalize()
norm.autoscale(x)
for i, (x_val, y_val) in enumerate(zip(x, y)):
    plt.plot(x_val, y_val, 'o', markersize=10, 
             color=reds(norm(x_val)),
             label='Point %s' % i
             )
plt.legend(numpoints=1, loc='lower right')

plt.show()

code output

Код должен быть достаточно понятным, но если вы хотите, чтобы я что-то перебирал, просто кричите.