Search code examples
pythonplotlyscatter-plotboxplot

Highlight a single point in a boxplot in Plotly


I have a boxplot in Plotly. I would like to overlay a single point on some of the boxes. I thought I could do this by adding a scatter trace to the fig, but when I look into the data of the figure I can't see anything specifying the y coordinate of the boxes so I'm not sure how to overlay the point. How can I add a single point to some boxes in a boxplot?

import plotly.graph_objects as go
import numpy as np

N = 10

fig = go.Figure(data=[go.Box(
    x=2.5 * np.sin(np.pi * i/N) + i/N + (1.5 + 0.5 * np.cos(np.pi*i/N)) * np.random.rand(10),
    ) for i in range(int(N))])

fig.update_layout(height=600)
fig

Result: enter image description here

Ideal Result:

enter image description here


Solution

  • If you don't specify y values for multiple boxplots, plotly assigns them y values of "trace 0",..."trace 9" in its coordinate system (even though you won't be able to see them when you look at the fig object, as you noticed).

    So you can calculate the mean (or whatever statistic is intended to be shown by the red scatter points), and pass the arguments x = [{mean1}, ... {mean9}] and y=["trace 0", ... "trace 9"] to go.Scatter and they will appear on the figure.

    For example:

    import plotly.graph_objects as go
    import numpy as np
    
    N = 10
    
    # for reproducibility
    np.random.seed(42) 
    
    boxplot_data = []
    scatter_mean = []
    for i in range(int(N)):
        data_array = 2.5 * np.sin(np.pi * i/N) + i/N + (1.5 + 0.5 * np.cos(np.pi*i/N)) * np.random.rand(10)
        boxplot_data += [go.Box(x=data_array)]
        scatter_mean += [np.mean(data_array)]
    
    
    fig = go.Figure(data=boxplot_data)
    fig.add_trace(go.Scatter(
        x=scatter_mean,
        y=[f"trace {i}" for i in range(len(boxplot_data))],
        mode='markers',
        marker=dict(color="red"),
        showlegend=False
    ))
    
    fig.update_layout(height=600)
    fig.show()
    

    enter image description here