Color specific points in a plotly express strip plot

Question:

Let’s take this sample dataframe :

import random

df=pd.DataFrame({'Id':list(range(1,101)), 'Value':[random.randint(0,50) for i in range(100)]})

I would like to create a plotly express strip plot in which id 5 and 10 are colored in red and the others in blue. I built the following function :

import plotly.express as px

def strip_plotly(df,col_value,col_hover=[],col_color=None,L_color=[]):
        
    if col_color is not None :
        L_color = ["red" if i in L_color else "blue" for i in df[col_color].values]
    else :
        L_color = ["blue"]*len(df.index)
        
    fig = px.strip(df, y=col_value,hover_data = col_hover,color_discrete_sequence = L_color)

    fig.update_layout({
            'plot_bgcolor': 'rgba(0,0,0,0)',
            'paper_bgcolor': 'rgba(0,0,0,0)',
        },
        hoverlabel=dict(
            #bgcolor="white", 
            font_size=12, 
            #font_family="Rockwell"
        ),
        xaxis={
            'title':"x",
            #'type':'log'
        },
        yaxis={'title':"y"},
        title={
            'text': "strip plot for stackoverflow",
            #'y':0.95,
            'x':0.5,
            'xanchor': 'center',
            'yanchor': 'top'}
    )

    fig.update_xaxes(showspikes=True, spikecolor = 'black', showline=True, linewidth=1,linecolor='black',
                     ticks = "outside", tickwidth = 1, tickcolor = 'black',ticklen = 5)
    fig.update_yaxes(showspikes=True, spikecolor = 'black', showline=True, linewidth=1,linecolor='black',
                     ticks = "outside", tickwidth = 1, tickcolor = 'black',ticklen = 5)
    
    fig.show()

But when I run the function :

strip_plotly(df,"Value",col_hover=["Id"],col_color="Id",L_color=[5,10])

I get only blue points (ids 5 and 10 are not red). Would you please explain me what’s wrong ?
enter image description here

Asked By: Ewdlam

||

Answers:

import random
import plotly.express as px
import numpy as np
import pandas as pd

df=pd.DataFrame({'Id':list(range(1,21)), 'Value':[random.randint(0,50) for i in range(20)]})


def strip_plotly(df,col_value,col_hover=[],col_color=None,L_color=[]):
    L_color = np.where(df["Id"].isin([5,10]), "red", "blue")

    # need two traces as color is in marker https://plotly.github.io/plotly.py-docs/generated/plotly.graph_objects.box.marker.html
    fig = px.strip(df.loc[L_color=="blue"], y=col_value,hover_data = col_hover,color_discrete_sequence = ["blue"])
    fig = fig.add_traces(px.strip(df.loc[L_color=="red"], y=col_value,hover_data = col_hover,color_discrete_sequence = ["red"]).data)
    fig = fig.update_traces(offsetgroup="1")

    fig.update_layout({
            'plot_bgcolor': 'rgba(0,0,0,0)',
            'paper_bgcolor': 'rgba(0,0,0,0)',
        },
        hoverlabel=dict(
            #bgcolor="white", 
            font_size=12, 
            #font_family="Rockwell"
        ),
        xaxis={
            'title':"x",
            #'type':'log'
        },
        yaxis={'title':"y"},
        title={
            'text': "strip plot for stackoverflow",
            #'y':0.95,
            'x':0.5,
            'xanchor': 'center',
            'yanchor': 'top'}
    )

    fig.update_xaxes(showspikes=True, spikecolor = 'black', showline=True, linewidth=1,linecolor='black',
                     ticks = "outside", tickwidth = 1, tickcolor = 'black',ticklen = 5)
    fig.update_yaxes(showspikes=True, spikecolor = 'black', showline=True, linewidth=1,linecolor='black',
                     ticks = "outside", tickwidth = 1, tickcolor = 'black',ticklen = 5)
    
    return fig.show()
    
strip_plotly(df,"Value",col_hover=["Id"],col_color="Id",L_color=[5,10])


enter image description here

Answered By: Rob Raymond

Here’s a much simpler solution.

  1. Create a ‘color’ column with the desired color
  2. Assign colors based on the values of that column (creates a separate trace for each color)
  3. Overlay traces on top of each other
df=pd.DataFrame({'Id':list(range(1,101)), 'Value':[random.randint(0,50) for i in range(100)]})

df['color'] = np.where(df['Id'].isin([5,10]), 'red', 'blue')

fig = px.strip(df, y='Value', color='color')

fig.update_traces(offsetgroup=0)

fig.show()

Figure

Answered By: amance
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.