简体   繁体   中英

How to correctly use colormaps for plotly express line mapbox?

I have trouble getting plotly.express.line_mapbox() present the lines with correct colors. The lines have a value 0..100%, which represents the usage of each line. From other SO questions and websites I am approaching it like this:

norm = matplotlib.colors.Normalize(0, 100)
colors = [[norm(0), "green"],[norm(60), "yellow"],[norm(100), "red"]]
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", colors)

Then I specify each color by:

RGBa = cmap(percUsage)    
colors.append(f'rgb({int(255 * RGBa[0])}, {int(255 * RGBa[1])}, {int(255 * RGBa[2])})')

Where percUsage = 0..100 .

In respect to that, I am building my Dataframe with each lines data and then create the figure.

df = pd.DataFrame(data=dict(name=names, lat=lats, lon=lons, load=loads, color=colors, hover=hoverText))
fig = px.line_mapbox(df, lat='lat', lon='lon', line_group='name', color='color')

But while c.test_colormap(cmap) shows the colors as expected, plotly.express.line_mapbox() behaves totally weird in terms of colors. The screenshot shows a line with the usage value of 9. I do not get, why it prints a blue color, which should not even be in my spectrum of color. Others are colored green or red but in no relation to percUsage . I seem to miss something important here.

Any help is appreciated :)

c.test_colormap(cmap) plotly.express.line_mapbox()

So i managed to solve my problem and would like to share my findings, in case anyone stumbles on this question. Here you find the docs .

TL;DR and my key takeaways:

Using a discrete color map( dict ) with str -keys and hex-colors( str ), while the dataframes 's(df) "colors" column is filled with the corresponding keys used in discr_map .

from colormap import rgb2hex
import matplotlib.colors

cmap = matplotlib.colors.LinearSegmentedColormap.from_list("gyr", [[0., 'green'], [0.5, 'yellow'], [1.0, 'red']], N=101)
discr_map = {}
for i in range(0, 101, 1):
    discr_map.update({"c"+str(i): rgb2hex(int(255 * cmap(i)[0]), int(255 * cmap(i)[1]), int(255 * cmap(i)[2]))})

fig = px.line_mapbox(df, lat='lat', lon='lon', line_group='name', color='color', color_discrete_map=discr_map)

I do not really understand, why the dataframe 's colors column does not work with the format rgb(255,100,0) . Maybe hex format is needed here, as well - I'll check that out sometime. This was confusing, since other mapbox s can handle rgb format. For that reason it was falling back to its standard color range, which obviously confused me.

color (str or int or Series or array-like) – Either a name of a column in data_frame, or a pandas Series or array_like object. Values from this column or array_like are used to assign color to marks.

Then I looked into the color_discrete_map argument and made that finally work.

color_discrete_map (dict with str keys and str values (default {})) – String values should define valid CSS-colors Used to override color_discrete_sequence to assign a specific colors to marks corresponding with specific values. Keys in color_discrete_map should be values in the column denoted by color. Alternatively, if the values of color are valid colors, the string 'identity' may be passed to cause them to be used directly.

This is how I create the discrete colormap. I think the most important catch here, is to use N=101 (or whatever value range you need) to normalize the spectrum to values ranging from 0..100 .

# initialize discrete colormap
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("gyr", [[0., 'green'], [0.5, 'yellow'], [1.0, 'red']], N=101)
discr_map = {}
for i in range(0, 101, 1):
    discr_map.update({"c"+str(i): rgb2hex(int(255 * cmap(i)[0]), int(255 * cmap(i)[1]), int(255 * cmap(i)[2]))})

Which is then passed into the figures color_discrete_map argument:

fig = px.line_mapbox(df, lat='lat', lon='lon', line_group='name', color='color', color_discrete_map=discr_map)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM