Skip to content
Advertisement

How to iterate over scatter data?

I am trying to plot a time series on a scatterplot with dropdown boxes using Plotly express. I have 2 traces filtered on some unique values in the “name” column of my data. I’m using the ‘color’ function on px.scatter to filter by this column. Since the traces have the same name, they are duplicated on the plot and I can’t tell which trace belongs to which ‘color’. I would like to change the names of each according to the color. I am trying to loop over fig.data, as I was able to store my values in a list labels (see below) but have not been successful in looping over names of the traces since it is of type scatter.

Earlier, I was able to hardcode it in the following way, however, I need it to be dynamic:

fig.data[0]['name'] = "color1 var1"
fig.data[1]['name'] = "color2 var1"
fig.data[2]['name'] = "color1 var2"
fig.data[3]['name'] = "color2 var2"

To make it dynamic I tried this and was able to update the values, but each of them updated to the last value in my list. I would like to update each value in the order of the list. Not sure how to do this.

labels = df['name'].unique().tolist()
for i in range(len(labels)):
    x = labels[i]+" Color2"
    labels.append(x)

for n in fig.data:
    for i in n:
        for q in range(len(labels)):
            if i == 'name':
                n[i] = labels[q]

Here is the code I used for the dropdown plot (data is a time series):

def tsplot(title,df):
# Create figure with secondary y-axis
    fig = make_subplots(specs=[[{"secondary_y": True}]])
    labels = df['name'].unique().tolist() #for var1
    
    for i in range(len(labels)):
        x = labels[i]+" for var2"
        labels.append(x)

    # Add traces
    trace1 = px.scatter(df, x="day", y="campaign_cpc", color="display_env_name", hover_name="display_env_name",
                       color_discrete_sequence=px.colors.qualitative.Set3).update_traces(
    mode="lines")

    trace2 = px.scatter(df, x="day", y="market_cpc", color="display_env_name", hover_name='display_env_name',
                        color_discrete_sequence=px.colors.qualitative.Antique,).update_traces(
    mode="lines")
    
    trace2.update_traces(yaxis="y2")
    
    fig.add_traces(trace1.data + trace2.data)

buttons = [{"label": t.name,
                    "method": "update",
                    "args": [{"visible": [t2.legendgroup == t.legendgroup for t2 in fig.data]}],
                     } for t in fig.data[0:3]]  

    fig.update_layout(
    updatemenus=[
        {   "y": 1.1,
            "buttons": buttons,
            "active": 0
            }
        ]
    )

Advertisement

Answer

I found a solution to changing the trace names with a for loop.

Please note: df['color'] contains var1 by default. When adding var2, we need not remove var1.

   labels = df['color'].unique().tolist()
    
    for i in range(len(labels)):
        x = labels[i]+" var2"
        labels.append(x)
    
    for n in range(len(fig.data)):
        fig.data[n].name = labels[n]
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement