Black Lives Matter. Please consider donating to Black Girls Code today.

Combining two plotly express figures with color subgroups

I am trying to combing a scatter plot and a line plot for a time course dataset which has several experimental replicates per time point. The scatter should just show all experimental replicate, while I want the line plot to show the mean for each time point (so the trendline options in scatter are not applicable).

Here is an example using the gapminder sample data:

import as px

px.defaults.template = 'simple_white'
px.defaults.width = 600
px.defaults.height = 400

df =
df = df[(df['country'].isin(['Kenya', 'Singapore', 'Uganda', 'Japan'])) & (df['year'] > 1990)]
fig_scatter = px.scatter(df, 'year', 'lifeExp', 'continent')


# Disable sorting to make sure the order is the same
df_agg = df.groupby(['continent', 'year'], as_index=False, sort=False).mean()
fig_line = px.line(df_agg, 'year', 'lifeExp', color='continent')


I have tried the add_trace, but it creates duplicated traces in the legend, which is redundant in this case. I would like there to be only one legend entry per color (ideally a point on a line, but it can also be just a point or just a line) and that both the line and scatter are controlled by clicking on this single legend entry. Is it possible to achieve this grouping manually?

for trace in


I also looked into add_scatter() method, but I did not see a way to group/color the data by a column in a data frame the same way plotly express does it. But maybe I just missed it?

What is the most straightfoward way to achieve what I describe? I am teaching Plotly to people who are coming from a background in excel and are without programming experience, so getting into too complicated ways of building up plots from geo objects is probably too complex (I would even skip the traces loop above if I could). Ideally, there would be a method for figures created with plotly express to combine them with each other, e.g. fig_scatter.add_px_fig(fig_line). I think this would be really intuitive, but realize it could be difficult to implement (although even a simple version that does the trace loop and groups legend items under the hood would be welcome).