Switching Marker Colors with Updatemenus

I would like to update the marker colors in a scatter plot with buttons (or dropdown menu). Although it seems like this should be straightforward, I’m running into some odd behavior that I’m hoping is due to me being a novice with plotly and not an issue with its functionality. Below is an example that I hope is minimal enough to be useful.

import plotly
import plotly.graph_objs as go

def get_color_set(color_set_id):
    if color_set_id == 1:
        marker_color = ['red', 'green', 'blue']
    elif color_set_id == 2:
        marker_color = ['black', 'blue', 'red']

    return [{'marker.color':marker_color}]


trace = go.Scatter(
    x=[0,1,1],
    y=[1,0,1],
    marker=dict(color=['green','black','red']),
    mode='markers'
)
updatemenus=list([
            dict(
                buttons=list([
                    dict(label = 'Color Set 1',
                         method = 'update',
                         args=get_color_set(1)
                    ),
                    dict(label = 'Color Set 2',
                         method = 'update',
                         args=get_color_set(2)
                    ),
                ]),
                direction = 'left',
                pad = {'r': 10, 't': 10},
                showactive = True,
                type = 'buttons',
                x = 0.1,
                xanchor = 'left',
                y = 1.1,
                yanchor = 'top'
            )
        ])
layout = go.Layout(
    title='Scatter Color Switcher',
    updatemenus = updatemenus
)

fig = go.Figure(data=[trace], layout=layout)
plotly.offline.plot(fig, filename='scatter_color_switcher.html')

This produces a scatter plot with 3 points colored green, black and red, and two buttons that are supposed to switch the colors to either [‘red’, ‘green’, ‘blue’] or [‘black’, ‘blue’, ‘red’]. The buttons ALMOST function as I want them to, but ALL points in the plot end up being the FIRST color in the list specified by the button press. Any insight into why this would be happening or any other solutions to the task I want to accomplish? Thank you!

Hi, have you found a solution?

Hi @iknowone and @nbosc,

I think the issue here is that the marker_color list needs to be wrapped in a second list.

return [{'marker.color': [marker_color]}];

The reason is that when an update operation receives a value that is a list, it applies one element to each trace. That’s why all of the points are being given the first color in the list. By wrapping an extra list around marker_color, the first element of the list is the marker_color list that you want.

Hope that helps,
-Jon

1 Like

Hi @jmmease,

Thank you for your help. That was it!

1 Like