#python #matplotlib #plotly #data-visualization #plotly-python
#python #matplotlib #графическое #визуализация данных #plotly-python
Вопрос:
У меня есть следующий график, данные которого (положение и значения цвета) поступают из внешнего источника:
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
data = go.Scatter({
'hoverinfo': 'text',
'marker': {'color': ['rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(30,136,229,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(30,136,229,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(101,103,181,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(30,136,229,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(30,136,229,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(30,136,229,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)'],
'line': {'color': ['rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(30,136,229,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(30,136,229,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(101,103,181,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(30,136,229,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(30,136,229,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(30,136,229,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(101,103,181,1.0)', 'rgba(101,103,181,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)', 'rgba(245,39,87,1.0)', 'rgba(245,39,87,1.0)', 'rgba(173,71,134,1.0)'],
'width': 0},
'size': 4.0,
'symbol': 'circle'},
'mode': 'markers',
'name': '',
'text': 'some hover text',
'x': [-0.003959869034588337, 0.005061251576989889, 0.006703123915940523, 0.0019563836976885796, -0.0034903099294751883, 0.01550869271159172, 0.0034700739197432995, -0.0018220042111352086, 0.010076701641082764, 0.005893221125006676, 0.006880240514874458, 0.008371046744287014, -0.011258691549301147, 0.006205271929502487, 0.006518206559121609, 0.0006746328435838223, 0.003603707766160369, 0.006014757324010134, 0.00443321093916893, 0.003568103536963463, -0.003682805225253105, -0.00819386076182127, -0.004438681993633509, -0.005338573828339577, -0.003959869034588337, 0.009993263520300388, -0.003959869034588337, -0.0022754939272999763, -0.006901460234075785, 0.004212438594549894, 0.0055755432695150375, 0.00879394169896841, 0.00341446022503078, -0.003105803159996867, -0.0017424229299649596, -0.003959869034588337, 0.003894187044352293, 0.00497738691046834, 0.007604200392961502, -0.002378312638029456, -0.003682805225253105, 0.006995890289545059, -0.0009093930711969733, -0.006481392774730921, -0.0005934620276093483, 0.000962280435487628, -0.005434616934508085, 0.007020855322480202, 0.003565214341506362, 0.0007076506153680384, -0.0010657859966158867, -0.004246561788022518, 0.004018908832222223, 0.00341446022503078, 0.008702066726982594, 0.003824896179139614, 0.005599078722298145, 0.001925327000208199, 0.00950327143073082, -0.004803186748176813, -0.004064114764332771, 0.0020236200653016567, -0.00015490801888518035, 0.005108738783746958, -0.0018468756461516023, 0.0026262067258358, -0.0017437718342989683, 0.003807958448305726, 0.006813774351030588, -0.009644323959946632, -0.009730380959808826, -0.0022573473397642374, 0.0046448661014437675, -0.0024109657388180494, 0.008578626438975334, 0.016399644315242767, 0.0031808093190193176, -0.014735744334757328, -0.001668736687861383, -0.0010972967138513923, 0.006214889232069254, -0.004786754958331585, 0.00018462195293977857, -0.003240009071305394, -0.008156259544193745, -0.0032861116342246532, -0.005193014163523912, -0.005338573828339577, 0.006094215903431177, 0.004020459949970245, -0.002630046335980296, -0.00510041881352663, 0.0034949760884046555, 0.013181162998080254, 0.005493168719112873, -0.0038349907845258713, 0.0087448013946414, -0.00782866682857275, -0.002721679862588644, 0.007046200335025787],
'xaxis': 'x',
'y': [-0.22, -0.12, -0.06, -0.06, 0.1, 0.01, -0.09, 0.07, -0.03, 0.0, 0.11, -0.07, 0.02, 0.13, -0.12, -0.09, 0.12, 0.01, -0.11, 0.1, -0.01, 0.02, -0.11, -0.05, 0.06, 0.02, 0.0, -0.11, 0.05, 0.08, -0.07, -0.03, 0.05, -0.1, -0.06, -0.04, -0.05, 0.15, -0.11, -0.12, 0.3, 0.05, 0.05, 0.0, -0.04, 0.02, -0.12, 0.17, 0.13, -0.01, 0.08, 0.02, 0.04, 0.0, -0.06, 0.04, -0.1, 0.02, 0.05, -0.04, 0.35, 0.05, -0.1, -0.05, -0.02, -0.03, 0.0, 0.02, -0.14, 0.04, 0.03, 0.1, 0.01, 0.15, -0.09, 0.01, -0.02, -0.01, -0.14, -0.08, -0.01, -0.06, 0.09, 0.03, -0.04, -0.05, -0.08, 0.0, 0.05, -0.01, -0.07, -0.1, -0.12, 0.01, 0.01, 0.15, -0.02, 0.04, -0.16, -0.07],
'yaxis': 'y'
})
layout=go.Layout(title="Some Plot", xaxis={'title':'x-axis label'})
init_notebook_mode(connected=True)
fig = go.Figure(data=[data], layout=layout)
iplot(fig)
Теперь я хочу добавить цветовую панель справа от рисунка, чтобы дать представление о том, что означают цвета. Для этого я взял словарь цветов, который напоминает цвета на графике, преобразовал их в цветовую карту с помощью функций matplotlib и преобразовал их в цветовую карту, совместимую с plotly, как показано в здесь примере:
from matplotlib.colors import LinearSegmentedColormap
import matplotlib
import numpy as np
cdict = {
'red': ((0.0, 0.12, 0.12),
(1.0, 0.96, 0.96)),
'green': ((0.0, 0.53, 0.53),
(1.0, 0.15, 0.15)),
'blue': ((0.0, 0.90, 0.90),
(1.0, 0.34, 0.34)),
'alpha': ((0.0, 1, 1),
(0.5, 1, 1),
(1.0, 1, 1))
}
red_blue = LinearSegmentedColormap('RedBlue', cdict)
def matplotlib_to_plotly(cmap, pl_entries):
h = 1.0/(pl_entries-1)
pl_colorscale = []
for k in range(pl_entries):
C = list(map(np.uint8, np.array(cmap(k*h)[:3])*255))
pl_colorscale.append([k*h, 'rgb' str((C[0], C[1], C[2]))])
return pl_colorscale
red_blue = matplotlib_to_plotly(red_blue, 255)
Если бы у меня был доступ к фактическим значениям, используемым для раскрашивания точек данных, я мог бы использовать их для рисования цветовой панели следующим образом: data['marker'] = dict(color=actual_color_values, colorscale=red_blue)
Итак, я попытался взять значения y из data
части самой фигуры, чтобы посмотреть, использовались ли они для раскрашивания точек. Но, по-видимому, нет, потому что результирующая фигура имеет другие цвета точек данных, чем исходная:
y = data['y']
data['marker'] = dict(color=y, colorscale=red_blue, colorbar=dict(thickness=10))
fig = go.Figure(data=[data], layout=layout)
iplot(fig)
Затем я попытался присвоить значения цвета значениям data['marker']['color']
. Но это приводит к пустой цветовой панели с неправильными пределами цветовой панели:
y = data['marker']['color']
data['marker'] = dict(color=y, colorscale=red_blue, colorbar=dict(thickness=10))
fig = go.Figure(data=[data], layout=layout)
iplot(fig)
Итак, я попробовал другой способ. Я создал фиктивную трассировку, используя эту цветовую карту, чтобы отобразить цветовую полосу с минимальными и максимальными значениями x и y, просматривая исходный график:
min_x = -0.015
max_x = 0.015
min_y = -0.3
max_y = 0.3
dummy_trace=go.Scatter(x=[min_x, max_x],
y=[min_y, max_y],
mode='markers',
marker=dict(
size=(max(y)-min(y))/100,
color=[min(y), max(y)],
colorscale=red_blue,
colorbar=dict(thickness=10),
showscale=True
),
hoverinfo='none'
)
layout = dict(xaxis=dict(visible=False), yaxis=dict(visible=False))
fig = go.Figure([dummy_trace], layout)
iplot(fig)
Теперь, если я могу каким-то образом просто отобразить эту цветовую панель рядом с фактическим графиком, это будет сделано. Есть ли какой-либо способ сделать это? И, если возможно, я также хотел бы удалить числа из цветовой панели и отобразить только High в верхней ее части и Low в нижней, потому что, как мы видели выше, минимальные и максимальные значения y не являются минимальными и максимальными фактическими значениями, используемыми для раскрашивания точек данных.
Ответ №1:
Я нашел способ добавить фиктивную трассировку к объекту figure; это с помощью add_trace
функции. И способ удалить числа из цветовой панели — заменить tickvals
и ticktext
параметры в colorbar
поле фиктивной трассировки на желаемые значения.
colorbar_trace = go.Scatter(x=[None],
y=[None],
mode='markers',
marker=dict(
colorscale=red_blue,
showscale=True,
cmin=-5,
cmax=5,
colorbar=dict(thickness=5, tickvals=[-5, 5], ticktext=['Low', 'High'], outlinewidth=0)
),
hoverinfo='none'
)
fig['layout']['showlegend'] = False
fig.add_trace(colorbar_trace)
iplot(fig)
Поскольку мне нужны только 2 значения в цветовой панели ( High
и Low
), я указываю 2 значения в tickvals; если, скажем, я указал 3 значения в colorbar
словаре с помощью tickvals=[-5, 0, 5], ticktext=['Low', 'Medium', 'High']
, это выглядело бы так:
Комментарии:
1. Спасибо, что разобрались с этим и вернулись, чтобы опубликовать решение! Это просто сэкономило мне так много времени.