Добавление цветовой шкалы в качестве легенды на диаграмму рассеяния matplotlib (несколько вспомогательных участков, несколько рассеивателей) - PullRequest
0 голосов
/ 18 октября 2018

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

Типичный пример кода:

import numpy as np
from matplotlib import pyplot as plt

x = range(50)
scales = np.linspace(0, 2, 7)
locs = range(4)
cmap = plt.get_cmap("Spectral")
for s_plot in range(4):
    plt.subplot(2, 2, s_plot+1)
    color = iter(cmap(np.linspace(0, 1, len(scales))))
    for scale in scales:
        c = next(color)
        y = np.random.normal(loc=locs[s_plot], scale=scale, size=50)
        plt.scatter(x, y, c=c, s=5)
        plt.title("Mean = {:d}".format(locs[s_plot]))
plt.subplots_adjust(hspace=0.4)
plt.show()

ВышеПример дает: enter image description here

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

enter image description here

Таким образом, цветная полоса не отображает значение моих точек рассеяния, а скорее различные «строки» (в данном случае: разные масштабы), которые проходят через.В примере, который поможет сопоставить точки с весами.

То, что я попробовал, - это простой

plt.colorbar()

, который вызывается один раз после завершения каждого подзаговора.Но я получаю TypeError: You must first set_array for mappable Кроме того, поскольку я хочу создать карту цветов для разных масштабов, я также попытался

plt.colorbar(scales) 

, которая возвращает: AttributeError: 'numpy.ndarray' object has no attribute 'autoscale_None'.

Я в настоящее времяне хватает ориентации на то, как действовать дальше.Изменить: я был отмечен как возможный дубликат matplotlib Colorbar для разброса .Я уже нашел этот вопрос, но он не помог с моей проблемой.В моем случае мне нужна цветовая карта, которая не зависит от z-значения, но будет указывать только «номер строки» или «scatter-row» или как вы хотите ее вызывать (эквивалентно «lines» в plt.plot).

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Цветная полоса нуждается в ScalarMappable в качестве ввода.Поэтому, если ни одна из вещей, созданных вами на вашем графике, не подходит для этого, вы можете создать ее самостоятельно.

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

x = range(50)
scales = np.linspace(0, 2, 7)
locs = range(4)
cmap = plt.get_cmap("Spectral")
norm = plt.Normalize(scales.min(), scales.max())

fig, axes = plt.subplots(2,2, constrained_layout=True, sharey=True)

for s_plot, ax in enumerate(axes.flat):
    for scale in scales:
        y = np.random.normal(loc=locs[s_plot], scale=scale, size=50)
        sc = ax.scatter(x, y, c=[cmap(norm(scale))], s=5)
        ax.set_title("Mean = {:d}".format(locs[s_plot]))

sm =  ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])
cbar = fig.colorbar(sm, ax=axes[:,1])
cbar.ax.set_title("scale")

plt.show()

enter image description here

0 голосов
/ 18 октября 2018

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

import matplotlib
norm = matplotlib.colors.Normalize(vmin=0, vmax=50)

ax = plt.gca()
matplotlib.colorbar.ColorbarBase(ax, cmap='viridis', norm=norm)

, где, конечно, вы можете использовать любые оси (или использовать inset_axes для размещения осей где-то определенное).

Более хитрым становитсяцвета для ваших точечных графиков, которые в первую очередь соответствуют цветовой карте.Я не уверен, что есть более простой способ, но я преобразую цвета в RGB для печати.Вот полный пример:

import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
import numpy as np

N = 10

# dummy data
x_ = [k/10*np.arange(10) for k in range(N)]

cmap = matplotlib.cm.get_cmap('viridis')
cmap_values = np.linspace(0., 1., N)
colors = cmap(cmap_values)

colors_rgb = ['#{0:02x}{1:02x}{2:02x}'.format(int(255*a), int(255*b), int(255*c)) for a, b, c, _ in colors]

plt.figure()

for x, c in zip(x_, colors_rgb):
    plt.plot(x, c=c)

norm = matplotlib.colors.Normalize(vmin=0, vmax=50)
ticks = np.arange(0, 60, 10)

# vertical colorbar
cbaxes = inset_axes(plt.gca(), width="3%", height="80%", loc=2)
cbar = matplotlib.colorbar.ColorbarBase(cbaxes, cmap=cmap, norm=norm, ticks=ticks)
cbar.set_label('scale')
cbar.ax.set_yticklabels(ticks, fontsize=12)

enter image description here

...