Manually customize colorbar - scatter python

I have data sorted by month of collection. I am trying to assign a varying color range specifically to season as well (ie. cooler months have cooler colors - light blue for October and gets darker towards January). I have been working from Continuous color scales and color bars in Python and this example Create colorbar from a source label (string) rather than integer? Python - #3 by spencerchad.

I cannot figure out how to prevent each section in colorscale from blending together – I would like it to look more categorical like in the example Create colorbar from a source label (string) rather than integer? Python - #3 by spencerchad.

Also if all of my months are categorized by number (Jan =1, Feb=2… Dec =12) in the dataset is there a way to just assign color to the month number rather than assigning to each ‘fraction’ of colorscale?

Below is my code and current figure.

color_names = [‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’, ‘May’, ‘June’, ‘July’, ‘Aug’, ‘Sept’, ‘Oct’, ‘Nov’, ‘Dec’]
color_vals = list(range(len(color_names)))
num_colors = len(color_vals)
colorscale = [
[0, ‘rgb(0,25,51)’], #jan
[0.083333, ‘rgb(0,102,102)’], #feb
[0.16666, ‘rgb(0,204,204)’], #mar
[0.24999, ‘rgb(0,255,255)’], #apr
[0.3333, ‘rgb(255,255,102)’], #may
[0.4166, ‘rgb(255,153,51)’], #june
[0.4999, ‘rgb(255,153,51)’], #jul
[0.58329, ‘rgb(255,0,0)’], #aug
[0.6666, ‘rgb(204,0,0)’], #sept
[0.74995, ‘rgb(204,229,255)’], #oct
[0.83328, ‘rgb(102,178,255)’], #nov
[0.9166, ‘rgb(0,128,255)’], #dec
[1, ‘rgb(0,76,153)’]
]

cmin = -0.5
cmax = num_colors-0.5

trace0=go.Scatter(x=O18, y=H2, mode=‘lines’, name=‘LMWL’, marker=dict(color=‘#000000’))
trace1=go.Scatter(x=df_upgrading.del18, y=df_upgrading.del2, marker = dict(size=7,
line=dict(width=1),
colorbar=dict(title=‘Month’,
tickvals= color_vals,
ticktext= color_names),
colorscale = colorscale,
cmin=cmin,
cmax=cmax,
color = df_upgrading.month),
mode=‘markers’, name=‘CT_all’)

layout = go.Layout(xaxis=dict(range=[-18, -10]),
yaxis=dict(range=[-140,-100]),
showlegend=False)

data = [trace0, trace1]
fig=go.Figure(data=data, layout=layout)

plotly.offline.iplot(fig)

@spencerchad, What you want is a discrete colorscale. Here https://community.plotly.com/t/colors-for-discrete-ranges-in-heatmaps/ is an example that can suggest how to change your colorscale to get a discrete one.

That helps - but raises another issue. Since I am using my colorbar to show the month the sample was collected and my months are categorized in the data set by number (Jan=1… Dec=12) I have to leave the first section blank because Jan is not referenced by 0. Is there a way to leave out this section when plotting the colorbar?

color_names = [‘’, ‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’, ‘May’, ‘June’, ‘July’, ‘Aug’, ‘Sept’, ‘Oct’, ‘Nov’, ‘Dec’]
color_vals = list(range(len(color_names)))
num_colors = len(color_vals)
colorscale = [
[0, ‘rgb(255,255,255)’], #Leave blank - no months are equal to 0.
[0.07692, ‘rgb(255,255,255)’],
[0.07692, ‘rgb(0,25,51)’], #Jan
[0.15385, ‘rgb(0,25,51)’],
[0.15385, ‘rgb(0,102,102)’], #Feb
[0.23077, ‘rgb(0,102,102)’],
[0.23077, ‘rgb(0,204,204)’], #Mar
[0.30769, ‘rgb(0,204,204)’],
[0.30769, ‘rgb(0,255,255)’], #Apr
[0.38462, ‘rgb(0,255,255)’],
[0.38462, ‘rgb(255,247,0)’], #May
[0.46154, ‘rgb(255,247,0)’],
[0.46154, ‘rgb(255,196,0)’], #June
[0.53846, ‘rgb(255,196,0)’],
[0.53846, ‘rgb(255,145,0)’], #July
[0.61538, ‘rgb(255,145,0)’],
[0.61538, ‘rgb(255,85,0)’], #Aug
[0.69231, ‘rgb(255,85,0)’],
[0.69231, ‘rgb(255,0,0)’], #Sept
[0.76923, ‘rgb(255,0,20)’],
[0.76923, ‘rgb(102,178,255)’], #Oct
[0.84615, ‘rgb(102,178,255)’],
[0.84615, ‘rgb(0,128,255)’], #Nov
[0.92308, ‘rgb(0,128,255)’],
[0.92308, ‘rgb(0,0,153)’], #Dec
[1, ‘rgb(0,0,153)’]
]

cmin = -0.5
cmax = num_colors-0.5

trace0=go.Scatter(x=O18, y=H2, mode=‘lines’, name=‘LMWL’, marker=dict(color=‘#000000’))
trace1=go.Scatter(x=df_upgrading.del18, y=df_upgrading.del2, marker = dict(size=7,
line=dict(width=1),
colorbar=dict(title=‘Month’,
tickvals= color_vals,
ticktext= color_names),
colorscale = colorscale,
cmin=cmin,
cmax=cmax,
color = df_upgrading.month),
mode=‘markers’, name=‘CT_all’)

layout = go.Layout(xaxis=dict(range=[-18, -10]),
yaxis=dict(range=[-140,-100]),
showlegend=False)

data = [trace0, trace1]
fig=go.Figure(data=data, layout=layout)

plotly.offline.iplot(fig)

I would like the little white block below January to not be included as this is essentially month=0.

Hi @spencerchad,

You’ll want to update your colorscale to include 12 (rather than 13) discrete regions. So your boundaries should be at:

import numpy as np
np.linspace(0, 1, 12 + 1)
array([0.        , 0.08333333, 0.16666667, 0.25      , 0.33333333,
       0.41666667, 0.5       , 0.58333333, 0.66666667, 0.75      ,
       0.83333333, 0.91666667, 1.        ])

rather than

np.linspace(0, 1, 13 + 1)
array([0.        , 0.07692308, 0.15384615, 0.23076923, 0.30769231,
       0.38461538, 0.46153846, 0.53846154, 0.61538462, 0.69230769,
       0.76923077, 0.84615385, 0.92307692, 1.        ])

Then set cmin to 0.5 (rather than -0.5) and cmax to 12.5.

Hope that helps!
-Jon

2 Likes