pythonplotlyplotly-express

Change the color, marker size and name of single value - Plotly scatter


I have a dataframe and I am using Plotly to draw a scatter plot. I want to change the color, size and name of just a single value there, e.g. datapoint "one". I am not sure how to do this. I have been trying for_each_trace aiming to change the marker shape but never works.

import plotly.express as px
import pandas as pd

df1=pd.DataFrame(index=['one','two','three','four'],data=[[3,4],[2,5],[2,3],[6,4]],columns=['a','b'])
fig1=px.scatter(df1, x="a", y="b",text=df1.index.astype(str))
fig1.update_traces(textposition='top center')

fig1.for_each_trace(
    lambda trace: trace.update(marker_symbol="square") if trace.name == 'one' else ())

enter image description here


Solution

  • The thing is that px doesn't create one trace per index, but one trace per unique value found in the data assigned to color (ie. if color is unset, all markers belong to the same trace) :

    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.

    You can add a column in the dataframe to distinguish highlighted point(s) from others and use this column as color when calling px.scatter :

    df1['c'] = ['highlighted' if one else 'normal' for one in df1.index == 'one']
    # or just 
    # df1['c'] = df1.index == 'one' # the above is just to get meaningful `trace.name`
    
    fig1 = px.scatter(df1, x="a", y="b", color="c", text=df1.index.astype(str))
    fig1.update_traces(textposition='top center')
    
    fig1.for_each_trace(lambda trace: trace.update(marker_symbol="square") if trace.name == 'highlighted' else ())
    

    You can also control the color order via color_discrete_sequence or color_discrete_map.