# Plotly Scatter Button to Select Column for Colorbar

**URL:** https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702
**Category:** 📊 Plotly Python
**Tags:** question
**Created:** [July 9, 2024, 4:15pm UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702 "2024-07-09T16:15:30Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![friendlypanda](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@friendlypanda](https://community.plotly.com/u/friendlypanda)
#### Post date: [July 9, 2024, 4:15pm UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/1 "2024-07-09T16:15:30Z")

</div>

I am trying to make a scatterplot where the column of the df for the colorbar is selected via a button/dropdown.

In pseudocode, what I am trying to do based on [this](https://community.plotly.com/t/creating-a-dropdown-slider-for-a-choropleth-map-with-plotly-express/49370):

```auto
px.scatter(df, x='A', y='B')
button1 = dict(method = "restyle",
                        args = ['color', df['Y']]
                        label = "Y")
button1 = dict(method = "restyle",
                        args = ['color', df['Z']]
                        label = "Z")
fig.update_layout(updatemenus=[dict(buttons=[button1, button2])])

```

However, the dropdown shows the options but is not actually adjusting the colorbar. Any tips?

I have also tried the suggestion in [here](https://community.plotly.com/t/dropdown-choose-pandas-df-column-and-update-plot-with-corresponding-data/9203/2) by just changing “y” to “color” in the button args but it does not change the colorbar when I do this.

Thank you for the help.

---

<div class="post-metadata">

### Author: ![farispriadi](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/farispriadi/32/26759_2.png) [@farispriadi](https://community.plotly.com/u/farispriadi)
#### Post date: [July 10, 2024, 10:45am UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/2 "2024-07-10T10:45:29Z")

</div>

Hi @friendlypanda ,

I have been trying this.  
**restyle** method is used to modify data attributes like colorscales, but I am affraid it cannot be use to modify color arguments.

The best approach that I have been using is **update** method.  
You can refer to this link below.

> **[Dropdown](https://plotly.com/python/dropdowns/#update-dropdown)**
>
> Detailed examples of Dropdown Menus including changing color, size, log axes, and more in Python.

Or if you want practical solution this code below maye can help you a bit.

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

df = px.data.iris()

fig = go.Figure()

fig.add_trace(
    go.Scatter(x=list(df.sepal_width),
               y=list(df.sepal_length),
               mode='markers',
               marker=dict(color=list(df.petal_width),colorscale="Blues"),
               name="Color By petal_width",

               ))

fig.add_trace(
    go.Scatter(x=list(df.sepal_width),
               y=list(df.sepal_length),
               mode='markers',
               marker=dict(color=list(df.petal_length),colorscale="Viridis"),
               name="Color By petal_length",
               visible=False,
               ))

button1 = dict(method = "update",
                        args = [{"visible": [True, False]}],
                        label = "petal_width")
button2 = dict(method = "update",
                        args = [{"visible": [False, True]}],
                        label = "petal_length")
fig.update_layout(updatemenus=[dict(buttons=[button1, button2])])

fig.update_traces(marker_size=10)
fig.show()

```

Hope this help.

---

<div class="post-metadata">

### Author: ![friendlypanda](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@friendlypanda](https://community.plotly.com/u/friendlypanda)
#### Post date: [July 10, 2024, 2:19pm UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/3 "2024-07-10T14:19:05Z")

</div>

Hi,

Thank you for the response. I have tried changing the method to “update”, and unfortunately still cannot get the expected behavior. A mock piece of code is below. The idea is the actual colorbar changes based on which column is selected but in this code, when I change the dropdown, the colorbar does not change.

Hope you are able to help with this.

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

df = pd.DataFrame({'test1': [1, 2, 3, 4], 'test2':[4, 5, 4, 7], 'test3':[7,8,10, 13]})
fig = px.scatter(df,x='test1', y="test2", color='test1', width=600, height=400, hover_data=['test1','test2'])

buttonlist = []
for col in df.columns:
    buttonlist.append(
    dict(
        args=['color', [df[str(col)]]],
        label=str(col),
        method='update'
        )
    )

fig.update_layout(
    title="Test data",
    updatemenus=[
        go.layout.Updatemenu(
            buttons=buttonlist,
            direction="down",
            pad={"r": 5, "t": 5},
            showactive=False,
            x=0.1,
            xanchor="left",
            y=1.1,
            yanchor="top"
        ),
    ],
    autosize=True
)
fig.show()

```

---

<div class="post-metadata">

### Author: ![farispriadi](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/farispriadi/32/26759_2.png) [@farispriadi](https://community.plotly.com/u/farispriadi)
#### Post date: [July 10, 2024, 2:57pm UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/4 "2024-07-10T14:57:18Z")

</div>

Hi @friendlypanda ,

Here modification of the code from your previous response.

The idea using method “update” is created 3 traces, and the selected dropdown will show the trace with color based on certain column and hide the other traces.

```auto
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd 

df = pd.DataFrame({'test1': [1, 2, 3, 4], 'test2':[4, 5, 4, 7], 'test3':[7,8,10, 13]})
# fig = px.scatter(df,x='test1', y="test2", color='test1', width=600, height=400, hover_data=['test1','test2'])

## this lines below are to define 3 traces that have different colorscales based on certain column.
fig = go.Figure()
fig.add_trace(
    go.Scatter(x=list(df.test1),
               y=list(df.test2),
               mode='markers',
               marker=dict(color=list(df.test1)),
               name="test1",

               ))

fig.add_trace(
    go.Scatter(x=list(df.test1),
               y=list(df.test2),
               mode='markers',
               marker=dict(color=list(df.test2)),
               name="test2",
               visible=False,
               ))

fig.add_trace(
    go.Scatter(x=list(df.test1),
               y=list(df.test2),
               mode='markers',
               marker=dict(color=list(df.test3)),
               name="test3",
               visible=False,
               ))

buttonlist = []
## This commented lines below are your previous code
# for col in df.columns:
# buttonlist.append(
# dict(
# args=['color', [df[str(col)]]],
# label=str(col),
# method='update'
# )
# )
## This lines are modified version using method update
for idx,col in enumerate(list(df.columns)):
    buttonlist.append(
    dict(
        # the idea is to show the trace of selected dropdown and hide the other traces.
        args=[{"visible": [idx==0, idx==1, idx==2]}],
        label=str(col),
        method='update'
        )
    )

fig.update_layout(
    title="Test data",
    updatemenus=[
        go.layout.Updatemenu(
            buttons=buttonlist,
            direction="down",
            pad={"r": 5, "t": 5},
            showactive=False,
            x=0.1,
            xanchor="left",
            y=1.1,
            yanchor="top"
        ),
    ],
    autosize=True
)
fig.show()

```

Hope this help.

---

<div class="post-metadata">

### Author: ![friendlypanda](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@friendlypanda](https://community.plotly.com/u/friendlypanda)
#### Post date: [July 10, 2024, 3:14pm UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/5 "2024-07-10T15:14:23Z")

</div>

Ah - this does indeed work. However it uses Plotly not Plotly express which does raise a view more questions:

Is there a way to do the “hover\_data” parameter of plotly express with several columns - i.e. before it would have been hover\_data=['test1, ‘test2’, ‘test3’].

Also, is there a way to do the category\_oirders parameter - in the real data we do not have numerical categories so setting the order s very important.

Lastly - is there a way to show and then title the colorbar based on which trace is visible?

Thank you very much for the help.

---

<div class="post-metadata">

### Author: ![farispriadi](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/farispriadi/32/26759_2.png) [@farispriadi](https://community.plotly.com/u/farispriadi)
#### Post date: [July 10, 2024, 3:57pm UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/6 "2024-07-10T15:57:52Z")

</div>

Hi @friendlypanda ,

To do “hover\_data” using plotly graph objects you can use `customdata` and `hovertemplate`.

> **[Hover](https://plotly.com/python/hover-text-and-formatting/#customizing-hover-text-with-a-hovertemplate)**
>
> Over 19 examples of Hover Text and Formatting including changing color, size, log axes, and more in Python.

Yes you can set category order on plotly graph object.  
for example you want to sort the x axis categories

```auto
fig.update_xaxes(categoryorder='category ascending')

```

Link below will be give you complete example to handle category order.

> **[Categorical](https://plotly.com/python/categorical-axes/#automatically-sorting-categories-by-name-or-total-value)**
>
> Over 11 examples of Categorical Axes including changing color, size, log axes, and more in Python.

To show colorbar title you can add on `marker` attribute on every traces.

```auto
fig.add_trace(
    go.Scatter(x=list(df.test1),
               y=list(df.test2),
               mode='markers',
               marker=dict(color=list(df.test1),
                                 colorbar=dict(title="Colorbar"),), # add colorbar title
               name="test1",

               ))

```

Hope this help.

---

<div class="post-metadata">

### Author: ![friendlypanda](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@friendlypanda](https://community.plotly.com/u/friendlypanda)
#### Post date: [July 10, 2024, 4:49pm UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/7 "2024-07-10T16:49:59Z")

</div>

Hi,

This was very helpful. One issue I am still running into is that the actual data is not numerical so when I do marker=dict(color=list(df.text1)), I get the below error.

With Plotly express, when I pass in a column of strings, each gets assigned a color and the colorbar is more like a legend. Is this possible with graph\_objects?

```auto
           turquoise, violet, wheat, white, whitesmoke,
            yellow, yellowgreen
      - A number that will be interpreted as a color
        according to scatter.marker.colorscale
      - A list or array of any of the above

```

---

<div class="post-metadata">

### Author: ![farispriadi](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/farispriadi/32/26759_2.png) [@farispriadi](https://community.plotly.com/u/farispriadi)
#### Post date: [July 11, 2024, 12:22am UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/8 "2024-07-11T00:22:52Z")

</div>

You can transform your categorical series that indicates color as list of number by using `map` function.

```auto
# convert list of text to list of number
 list(map(lambda x : df.text1.unique().tolist().index(x),df.text1.tolist()))

```

if you put into `marker` attribute

```auto
marker=dict(color=list(map(lambda x : df.text1.unique().tolist().index(x),df.text1.tolist()))),

```

---

<div class="post-metadata">

### Author: ![friendlypanda](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@friendlypanda](https://community.plotly.com/u/friendlypanda)
#### Post date: [July 11, 2024, 12:50am UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/9 "2024-07-11T00:50:58Z")

</div>

Hi,

Thanks for the response.

This works to do the coloring but from this point I am not sure how to do the legend. My desired behavior is identical to the plotly express behavior - it’ll have the categories and their corresponding color.

Let me know if this makes sense.

For example, the Plotly Express version is:

```auto
df = pd.DataFrame({'test1': [1, 2, 3, 4], 'test2':[10, 8, 1, 10],'test5':['a', 'b','c', 'd']})
fig2 = px.scatter(df, x='test1', y='test2', color='test5', width=600, height=400)
fig2.show()

```

And this is the result with plotly express:

 ![Screenshot 2024-07-10 at 7.52.50 PM](https://us1.discourse-cdn.com/flex024/uploads/plot/original/3X/9/1/91d06cec887e5e6ac16c5b71051ca398ff42e626.png)

---

<div class="post-metadata">

### Author: ![farispriadi](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/farispriadi/32/26759_2.png) [@farispriadi](https://community.plotly.com/u/farispriadi)
#### Post date: [July 11, 2024, 2:31am UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/10 "2024-07-11T02:31:16Z")

</div>

Hi @friendlypanda,

I see,  
This lines below maybe a hack of modified code, but I hope this is help you solve your issues.

I try to create traces using Plotly express, I add 2 additional columns of dataframe, so the df have 5 columns `['test1','test2','test3','test4','test5']`.

```auto
df = pd.DataFrame({'test1': [1, 2, 3, 4], 'test2':[4, 5, 4, 7], 'test3':['a','b','c', 'd'],'test4':['E','F','G', 'H'],'test5':['W','X','Y', 'Z']})

```

The dropdown menu options will be [‘test3’,‘test4’,‘test5’], so the color will be using this 3 columns.

```auto
fig1 = px.scatter(df,x='test1', y="test2", color='test3', width=600, height=400, hover_data=['test1','test2'])
fig2 = px.scatter(df,x='test1', y="test2", color='test4', width=600, height=400, hover_data=['test1','test2'])
fig3 = px.scatter(df,x='test1', y="test2", color='test5', width=600, height=400, hover_data=['test1','test2'])

```

Creating traces by using Plotly Express will keep the discreate color feature on the traces, so the it will show the categorical color instead continuous colorbar. ( And actually you can use Plotly graph objects as well but you need create all traces manually)

Get all traces from all plotly express figures by using `fig1.data`, `fig2.data`,`fig3.data` into new Figure objects `fig`.

```auto
# Get the Sactter traces and add into new Figure object `fig` 
fig = go.Figure()
fig.add_traces(fig1.data) # fig1.data is tuple of traces
fig.add_traces(fig2.data)
fig.add_traces(fig3.data)

```

For initial view set the visible traces just for `test3`

```auto
fig.for_each_trace(
    lambda trace: trace.update(visible=False) if trace.name not in df.test3.unique().tolist() else ()
)

```

To update legend by selected dropdown options, you need to add this line to `args` attribute.

```auto
{"legend": {"title": {"text": col}}} # Update the legend of discrete color

```

Finally set `test3` as initial legend title

```auto
fig.update_layout(
    title="Test data",
    legend_title_text="text3", # initial color legend
    ..

```

And here is the complete code.

```auto
import plotly.graph_objects as go
import plotly.express as px
import pandas as pd 

df = pd.DataFrame({'test1': [1, 2, 3, 4], 'test2':[4, 5, 4, 7], 'test3':['a','b','c', 'd'],'test4':['E','F','G', 'H'],'test5':['W','X','Y', 'Z']})

## Create 3 figures with different color based on 3 column.
fig1 = px.scatter(df,x='test1', y="test2", color='test3', width=600, height=400, hover_data=['test1','test2'])
fig2 = px.scatter(df,x='test1', y="test2", color='test4', width=600, height=400, hover_data=['test1','test2'])
fig3 = px.scatter(df,x='test1', y="test2", color='test5', width=600, height=400, hover_data=['test1','test2'])

# Get the Sactter traces and add into new Figure object `fig` 
print(fig1.data)
fig = go.Figure()
fig.add_traces(fig1.data) # fig1.data is tuple of traces
fig.add_traces(fig2.data)
fig.add_traces(fig3.data)

# For initial view set the visible traces just for `test3` 
fig.for_each_trace(
    lambda trace: trace.update(visible=False) if trace.name not in df.test3.unique().tolist() else ()
)

buttonlist = []

## This lines are modified version using method update
for col in ["test3","test4","test5"]:
    buttonlist.append(
    dict(
        # the idea is to show the trace of selected dropdown and hide the other traces.
        args=[{"visible": [col=='test3']*len(df.test3.unique()) \
                          + [col=='test4']*len(df.test4.unique()) \
                          + [col=='test5']*len(df.test5.unique())
                },
                {"legend": {"title": {"text": col}}} # Update the legend of discrete color
              ],
        label=str(col),
        method='update'
        )
    )

fig.update_layout(
    title="Test data",
    legend_title_text="text3", # initial color legend
    updatemenus=[
        go.layout.Updatemenu(
            buttons=buttonlist, 
            direction="down",
            pad={"r": 5, "t": 5},
            showactive=False,
            x=0.1,
            xanchor="left",
            y=1.1,
            yanchor="top"
        ),
    ],
    autosize=True
)
fig.show()

```

---

<div class="post-metadata">

### Author: ![friendlypanda](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@friendlypanda](https://community.plotly.com/u/friendlypanda)
#### Post date: [July 11, 2024, 8:54pm UTC](https://community.plotly.com/t/plotly-scatter-button-to-select-column-for-colorbar/85702/11 "2024-07-11T20:54:56Z")

</div>

Thank you very much! This will make the plots I am making much nicer, so I really appreciate the help.
