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

How to copy color from one trace to another?

This may be a FAQ, but I can’t find the answer anywhere, and can’t figure out a way to do it that isn’t really ugly. If I have pairs of lines that I add to a plot, how can I make sure the second of each line pair uses the same color as the first line?

Here’s an example:

I want the dotted lines (representing model) to match the color of the lines representing the experimental data.

Obviously, in this case, I can manually say line_color=‘red’, ‘blue’ etc. But this rapidly becomes painful if I have many pairs of lines:

Is there a way to get a reference to another line and copy color automatically assigned to it? Or some standard way to handle this situation?

Thanks!

Hi dr_dom,
I don’t know how to retrieve the properties of a specific component (go.Scatter() trace), but to get to have many pairs of solid / dotted line traces, here is what I would set to do :

  1. Import the itertools library

    import itertools
    
  2. Load a colour palette as a list of strings. You can manually choose the colours, or use Plotly built-in sequential or diverging ones. Have a look there :
    https://plotly.com/python/builtin-colorscales/
    Let’s take an example with the built-in Viridis colour palette (but you can choose your own colours, it’s just a list of strings)

    import plotly.express as px
    col_pal = px.colors.sequential.Viridis
    
  3. Before creating your traces, make a cyclic iterator out of the colour palette list (make sure you have enough colours in your colour palette though) :

    col_pal_iterator = itertools.cycle(col_pal) 
    

Now each time you use next(col_pal_iterator), you’ll obtain the next element of the colour palette

  1. Loop through the pairs of lines (solid / dotted), and select a new colour to assign to both traces with line_color

    for k in range(number_of_pairs):
        new_colour = next(col_pal_iterator)
        trace_solid = go.Scatter(x=x_data, y=y_solid, mode = "lines", 
                                 line = dict(color = new_colour, dash="solid"))
        trace_dash = go.Scatter(x=x_data, y=y_dash, mode = "lines", 
                                       line = dict(color = new_colour, dash="dash"))
    

Maybe that’s not the answer you were looking for, but that is how I would approach your goal without spending too much energy whatever the number of pairs of lines.
However, I am interested to know if there is a way to indeed access the properties of a component like a scatter plot trace, should you or someone else find a better answer.
Good luck with your plots!

@Ouwa, that’s super helpful. Thank you.

I thought about generating my own color palette, but (1) I didn’t know how to access the palettes built in to Plotly, and (2) I thought I was going to have to keep a counter and then do some something ugly like:

color = color_palette[counter%len(color_palette)]

Not horrible, I guess. But the itertools.cycle() function feels much cleaner.

Appreciate the help!

1 Like