I have a figure with 3 line scatters, and for each of them I want to mark a specific point. I’m doing so by adding for each another scatter with a single point in the x, y I want.
I would like for the scatter and the single-point scatter to have the same color, which I can define explicitly but I also want to be able to not decide on the colors in the creation of the figure and be able to later control it using themes/templates.
So I’m looking for a solution to put two scatter traces in the same “color group” without defining the color explicitly.
import numpy as np
import plotly.graph_objects as go
size = 10
x = list(range(size))
y = {
'a': np.random.rand(size),
'b': np.random.rand(size),
'c': np.random.rand(size)
}
index_to_higlight = {
'a': 2,
'b': 5,
'c': 1
}
fig = go.Figure()
for plot in ['a', 'b', 'c']:
# Both scatters should have the same color!
# but colors should be editable later using templates
fig.add_trace(go.Scatter(x=x, y=y[plot], name=plot))
fig.add_trace(go.Scatter(x=[x[index_to_higlight[plot]]],
y=[y[plot][index_to_higlight[plot]]],
mode='markers',
marker_size=25,
showlegend=False))
Hi @matanper! I know it’s been a long time since you posted but I found a solution and I wanted to share it here in case somebody arrives here trying to solve the same problem.
With this code the colors for the markers and the lines would be the same and they would change if the template does:
fig = go.Figure()
for i, plot in enumerate(['a', 'b', 'c']):
fig.add_trace(go.Scatter(x=x, y=y[plot],
marker_color = fig.layout['template']['layout']['colorway'][i]))
fig.add_trace(go.Scatter(x=[x[index_to_higlight[plot]]],
y=[y[plot][index_to_higlight[plot]]],
mode='markers',
marker_size=25,
marker_color=fig.layout['template']['layout']['colorway'][i],
showlegend=False))
Another option is to give both traces (line + point to highlight) the same name and apply later a conditional update_traces:
fig = go.Figure()
for i, plot in enumerate(['a', 'b', 'c']):
fig.add_trace(go.Scatter(x=x, y=y[plot],
name = plot,
mode = 'lines+markers')
fig.add_trace(go.Scatter(x=[x[index_to_higlight[plot]]],
y=[y[plot][index_to_higlight[plot]]],
name = plot,
mode='markers',
marker_size=25,
showlegend=False))
fig.update_traces(
marker=dict(color=fig.layout['template']['layout']['colorway'][i]),
selector=dict(name=plot))
It’s better than what I had so far, but the solution is still only halfway for me. My use-case is creating the plots in one system, and then saving them and loading them in other systems (which might have different themes), but looks like in your solution the plots will be saved with the theme that was active at creation time.
The best solution for me would be to have a “marker color index” which accepts index instead of direct color.
But I guess it would have the same problem (it uses the active template in the first system). Although you could use it in combination with the second solution from the previous post. When you ‘load’ the figures in the second system, you can apply:
import plotly.io as pio
for i, plot in enumerate(['a', 'b', 'c']):
fig.update_traces(
marker_color = pio.templates[pio.templates.default]['layout']['colorway'][i],
selector=dict(name=plot))
If you want a more automated system (not having to remember the traces names):
import plotly.io as pio
traces = list(set(
[fig.data[trace].name for trace in range(len(fig.data)) if fig.data[trace].name is not None]
))
for i, plot in enumerate(traces):
fig.update_traces(
marker_color = pio.templates[pio.templates.default]['layout']['colorway'][i],
selector=dict(name=plot))