How to create multiple colorbars in a scattermapbox

Hi, I have a dataframe that has lat, long, speed, and mode. Mode is a categorical data and I’d like to plot different colorbars based on the mode.

Below is what I’d like to end up plotting: each mode having its own colorbar, and the data is colored by speed.

Using this code, I’m able to get it to work when dealing with one drive mode only,

fig = px.scatter_mapbox(df[df[ā€˜drive_mode’] == ā€˜mode1’], lat=ā€œLatā€, lon=ā€œLonā€, color=ā€˜VHW_Speed’,
labels = {ā€˜VHW_Speed’: ā€˜mode1 Speed’})

how do I add a second set of the dataframe with its own unique colorbar? When I try to assign a second subsection of the dataframe using:

fig1 = (df[df[ā€˜mode’] == ā€˜mode2’] yada yada)
then:
fig.add_trace(fig1)

the datapoints from the second fig shows up, but I still only get the colorbar from the first fig.

Apologies if I’m using the incorrect terminologies. initially I was searching up terms like ā€œmultiple legends with range of valuesā€ and I think one post online said it was called a colorbar…

2 Likes

Does anyone know if there’s a way to do this in the Python Plotly implementation, perhaps with separate overlaid data for each mode? Not that it helps here, but I’m also curious if in the Plotly JavaScript language it’s possible to get multiple different colorbar legends to display for a single trace?

I’m following your question @RSDummy.

Hotfix update:

I managed to find a way to generate multiple colorbars; however, it is hard coded - the length and position of the colorbars are fixed.

looks a little something like this,

fig0 = px.scatter_mapbox(dff, lat=ā€œLatā€, lon=ā€œLonā€)
fig0.data[0].marker = dict(
colorscale=ā€˜blues’,
colorbar = dict(x=1,y=.9, len = 0.25),
color = ā€˜Speed’,)
fig.add_trace(fig0.data[0])

and repeat for successive fig1, fig2 etc, the positioning and length of the colorbar is controlled using the x,y, and len respectively.

I honestly do not understand how the numbers work for the x and y work. Based on the documentation in link they both range from [-2,3]; however, I don’t understand what each value represents (0<x<1 make the most sense to me, y works very differently…) , and resorted to hard coding the numbers myself.

I wanted to implement this multi-colorbar inside a loop, but I couldn’t come up with a formula that would adjust the x and y position of the successive colorbars dynamically.

Oh well, another day of terrible code I guess.

image to show what I ended up with, unfortunately when I disable specific data corresponding to a colorbar, the hard code reveals its nastiness

hard coded update #2…

by manually figuring out the y, I’ve managed to implement a dynamic colorbar length, terrible code for those who just wants something that works…

count = 0
len_offset = { 1:0.375, 2:0.125, 3:0.125/3, 4:0 }
manual_colorscales = {1:ā€˜blues’, 2:ā€˜reds’, 3:ā€˜electric’, 4:ā€˜greens’}
for i, txt in enumerate([ā€˜SGT XCON’, ā€˜PGT XCON’, ā€˜SHAFT STP’, ā€˜TWO XCON’]):
n = len(checklist)
if txt in checklist:
figx = px.scatter_mapbox(dff[dff[ā€˜drive_mode’] == txt], lat=ā€œLatā€, lon=ā€œLonā€)
figx.data[0].marker = dict(
colorscale=manual_colorscales[i+1],
colorbar = dict(x=1,y= 0.875 - (count/n) - len_offset[n] , len = 1/n, title = txt),
color = dff[dff[ā€˜drive_mode’] == txt][plot_val])
count+=1
fig.add_trace(figx.data[0])

fig.update_layout(mapbox_style= ā€˜light’, mapbox_accesstoken=token, margin=dict(l=0,r=0,b=0,t=0))