Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plotly: How to get the trace color attribute in order to plot selected marker with same color?

I am trying to plot a selected marker for each of my traces in plotly. I would like to assign the same color to marker and line. Is there a way how to get the color attribute of my traces?

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5],
    y=[0, 3, 5, 7, 9, 11],
    name='trace01',
    mode='lines+markers',
    marker=dict(size=[0, 0, 30, 0, 0, 0],
            color=[0, 0, 10, 0, 0, 0])
))
fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5],
    y=[3, 5, 7, 9, 11, 13],
    name='trace02',
    mode='lines+markers',
    marker=dict(size=[0, 0, 0, 30, 0, 0],
            color=[0, 0, 0, 10, 0, 0])
))
fig.show()

enter image description here

like image 372
Christian Avatar asked Apr 21 '20 21:04

Christian


People also ask

How do you use color scales in Plotly?

Color Scales in Plotly ExpressBy default, Plotly Express will use the color scale from the active template's layout. colorscales. sequential attribute, and the default active template is plotly which uses the Plasma color scale. You can choose any of the built-in color scales, however, or define your own.

What is Add_trace in Plotly?

Adding Traces To Subplots If a figure was created using plotly. subplots. make_subplots() , then supplying the row and col arguments to add_trace() can be used to add a trace to a particular subplot.

What is XREF in Plotly?

By default, text annotations have xref and yref set to "x" and "y" , respectively, meaning that their x/y coordinates are with respect to the axes of the plot.

What is opacity in Plotly?

Opacity. Setting opacity outside the marker will set the opacity of the trace. Thus, it will allow greater visibility of additional traces but like fully opaque it is hard to distinguish density. import plotly.graph_objects as go # Generate example data import numpy as np x = np. random.


2 Answers

Updated answer for newer versions of plotly:

For recent plotly versions, a larger number of the attributes of a plotly figure object are readable through fig.data. Now you can retrive the color for a line without defining it or following a color cycle through:

fig.data[0].line.color

To make things a bit more flexible compared to my original answer, I've put together an example where you can have multiple markers on the same line. Markers are organized in a dict like so:

markers = {'trace01':[[2,5], [4,9]],
           'trace02':[[3,9]]}

And the essence of my approach to getting the plot below is this snippet:

for d in fig.data:
    if d.name in markers.keys():
        for m in markers[d.name]:
            fig.add_traces(go.Scatter(x=[m[0]], y = [m[1]],
                                      mode='markers',
                                      name=None,
                                      showlegend=False,
                                      marker=dict(color=d.line.color,size=15)
                                     )
                          )

Here you can see that I'm not actually using fig.data[0].line.color, but rather color=d.line.color since I've matched the markers with the traces by name through :

for d in fig.data:
    if d.name in markers.keys():
        for m in markers[d.name]:

Plot:

enter image description here

Complete code:

import plotly.graph_objects as go

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5],
    y=[0, 3, 5, 7, 9, 11],
    name='trace01',
    line=dict(color='blue'),
    mode='lines',
   
))
fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5],
    y=[3, 5, 7, 9, 11, 13],
    name='trace02',
    line=dict(color='red'),
    mode='lines'
    
))

markers = {'trace01':[[2,5], [4,9]],
           'trace02':[[3,9]]}

for d in fig.data:
    if d.name in markers.keys():
        for m in markers[d.name]:
            fig.add_traces(go.Scatter(x=[m[0]], y = [m[1]],
                                      mode='markers',
                                      name=None,
                                      showlegend=False,
                                      marker=dict(color=d.line.color,size=15)
                                     )
                          )
            
fig.show()

Original answer for older versions

You can retrieve the color of a trace using:

fig['data'][0]['line']['color']

But you'll have to specify the color of the trace to be able to do so. Or you can make sure that the color of the markers follow the same sequence as the traces. But we can get to all the details if this is in fact what you're trying to accomplish:

enter image description here

If you study the code snippet below, you'll see that I, unlike you, havent defined the markers in the same go as the lines. Rather, I've added the traces as pure lines with mode='lines' and then added separate traces for the markers with mode='markers'. When doing the latter, I've retrieved the colors of the corresponding lines using color=data['line']['color'] in a loop:

import plotly.graph_objects as go

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5],
    y=[0, 3, 5, 7, 9, 11],
    name='trace01',
    line=dict(color='blue'),
    mode='lines',
   
))
fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5],
    y=[3, 5, 7, 9, 11, 13],
    name='trace02',
    line=dict(color='red'),
    mode='lines'
    
))

markers = [[2,5],
           [3,9]]

for i, data in enumerate(fig['data']):
    #print(data['line']['color'])
    fig.add_trace(go.Scatter(x=[markers[i][0]], y=[markers[i][1]],
                   mode='markers',
                   name=None,
                   showlegend=False,
                   marker=dict(color=data['line']['color'],
                               size=15
                    )))
fig.show()

Edit 1: How to do the same by referencing the default color sequence

By default, plotly follows a color sequence that can be found using px.colors.qualitative.Plotly:

['#636EFA',
 '#EF553B',
 '#00CC96',
 '#AB63FA',
 '#FFA15A',
 '#19D3F3',
 '#FF6692',
 '#B6E880',
 '#FF97FF',
 '#FECB52']

The following snippet will produce the exact same figure as before, but without having to define the colors for the traces.

import plotly.graph_objects as go
import plotly.express as px

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5],
    y=[0, 3, 5, 7, 9, 11],
    name='trace01',
    mode='lines',

))
fig.add_trace(go.Scatter(
    x=[0, 1, 2, 3, 4, 5],
    y=[3, 5, 7, 9, 11, 13],
    name='trace02',
    mode='lines'

))

colors = px.colors.qualitative.Plotly

markers = [[2,5],
           [3,9]]

for i, data in enumerate(fig['data']):
    #print(data['line']['color'])
    fig.add_trace(go.Scatter(x=[markers[i][0]], y=[markers[i][1]],
                   mode='markers',
                   name=None,
                   showlegend=False,
                   marker=dict(color=colors[i],
                               size=15
                    )))
fig.show()
like image 157
vestland Avatar answered Sep 22 '22 19:09

vestland


Adding to the above answer, remember that Plotly in px.colors.qualitative.Plotly is the name of the color scheme used in the current template, which defaults to Plotly. You can use other color schemes, check their names and colors by doing this

import plotly.express as px

fig = px.colors.qualitative.swatches()
fig.show()

[Reference: https://plotly.com/python/discrete-color/]

like image 24
SOf_PUAR Avatar answered Sep 22 '22 19:09

SOf_PUAR