Search code examples
pythonplotplotly

plotly graph object colors to similar


I try to plot values using plotly graph objects, and use one column to set the color.

fig_1.add_trace(
    go.Scattermapbox(
            lat=data.latitude, 
            lon=data.longitude,
            marker=go.scattermapbox.Marker(size=9, color=data.id_nr),   
            )
        )

However, the values are very high numbers (id numbers, int64) and thereby, id numbers which are closer to each other (100k different rather than 1M) will appear almost as the same color.

Is there a way to set the colours as discrete colours? using

... color=data.id_nr.astype(str) 

as used in Plotly express to make the coolers discrete does not work.

Invalid element(s) received for the 'color' property of scattermapbox.marker

The basic question is: Can you set the colors that each value, however how close or distanced the delta is, gets a unique color?


EDIT: The id values are more like:

id=[1,2,5,100004,100007,100009]

In combination with continuous coloring by plotly, the first three and the last three are kind of identically in color. Plotly express solves this with changing the int values (of id) to strings, making them discrete.


EDIT2 :

A solution would be to separate the data by ID Then add a trace for each ID. However, this is not ..."sexy" and I would rather know a solution with plotly handling the colors discretely.


Solution

  • I recreated the data and created the code by adapting the example from the official reference to your assignment. The format of the data is a data frame with three columns: id column, latitude and longitude, and location name. In the definition of the marker, I used the id column to define the color, and specified 'Viridis' as the color scale, which is a continuous color map. See this for a concrete example of introducing a color scale in a scatter plot.

    import pandas as pd
    import plotly.express as px
    
    lat = [38.91427,38.91538,38.91458,38.92239,38.93222,38.90842,38.91931,38.93260,38.91368,38.88516,38.921894,38.93206, 38.91275]
    lon = [-77.02827,-77.02013,-77.03155,-77.04227,-77.02854,-77.02419,-77.02518,-77.03304,-77.04509,-76.99656,-77.042438,-77.02821,-77.01239]
    name = ["The coffee bar","Bistro Bohem","Black Cat", "Snap","Columbia Heights Coffee","Azi's Cafe", "Blind Dog Cafe","Le Caprice","Filter","Peregrine","Tryst","The Coupe","Big Bear Cafe"]
    ids =  [1,2,3,4,5001,5002,5003,5004,100004,100007,100009,100010,100011]
    colors = px.colors.qualitative.Alphabet[:len(lat)]
    
    df = pd.DataFrame({'id':ids, 'lat':lat,'lon':lon,'name':name,'colors': colors})
    
    df.head()
        id  lat     lon     name    colors
    0   1   38.91427    -77.02827   The coffee bar  #AA0DFE
    1   2   38.91538    -77.02013   Bistro Bohem    #3283FE
    2   3   38.91458    -77.03155   Black Cat   #85660D
    3   4   38.92239    -77.04227   Snap    #782AB6
    4   5001    38.93222    -77.02854   Columbia Heights Coffee     #565656
    
    import plotly.graph_objects as go
    
    mapbox_access_token = open("mapbox_api_key.txt").read()
    
    fig = go.Figure(go.Scattermapbox(
            lat=df['lat'],
            lon=df['lon'],
            mode='markers',
            marker=go.scattermapbox.Marker(
                size=16,
                color=df['colors'],
                #colorscale='Viridis'
            ),
            text=df['name'],
        ))
    
    fig.update_layout(
        autosize=False,
        width=1000,
        height=500,
        hovermode='closest',
        mapbox=dict(
            accesstoken=mapbox_access_token,
            bearing=0,
            center=dict(
                lat=38.92,
                lon=-77.07
            ),
            pitch=0,
            zoom=11
        ),
    )
    
    fig.show()
    

    enter image description here