如何在已经存在的绘图中添加颜色条?

时间:2019-04-01 01:43:53

标签: python matplotlib plotly data-visualization 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) 

enter image description here

现在,我想在图的右侧添加一个色条,以指示颜色的含义。为此,我采用了类似于图中颜色的颜色字典,使用matplotlib函数将其转换为颜色图,然后将其转换为与图形兼容的颜色图,如示例here中所示:

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)

因此,我尝试从图形本身的data部分获取y值,以查看这些y值是否用于为点着色。但显然不是,因为所得图形的数据点颜色与原始图形不同:

y = data['y']
data['marker'] = dict(color=y, colorscale=red_blue, colorbar=dict(thickness=10))
fig = go.Figure(data=[data], layout=layout)
iplot(fig)

enter image description here

然后,我尝试为颜色值分配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)

enter image description here


所以我尝试了另一种方法。我通过使用此色图进行了虚拟跟踪,以通过从原始图上眼球观察来显示带有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)

enter image description here

现在,如果我能以某种方式仅在实际图的旁边显示此颜色栏,它将完成此操作。有什么办法吗?而且,如果可能的话,我也想从颜色栏中删除数字,并在其顶部仅显示高,而在其底部仅显示低,因为如上所述,最小值和最大值y值不是用来给数据点着色的实际值的最小值和最大值。

1 个答案:

答案 0 :(得分:0)

我找到了将虚拟轨迹添加到图形对象的方法; add_trace函数。从颜色栏中删除数字的方法是用所需的值替换虚拟轨迹的tickvals字段中的ticktextcolorbar参数。

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)

enter image description here

由于我只希望颜色栏中有2个值(HighLow),因此我在tickvals中指定了2个值;例如,如果我在colorbar字典中用tickvals=[-5, 0, 5], ticktext=['Low', 'Medium', 'High']指定了3个值,则看起来像这样:

enter image description here