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

The "update" method for dropdown menues does not appear to be working

Hi everyone,

I can’t get the “update” method to work. I want to use a drop down menu change the data presented as well as the annotations with a dropdown menu. I am attaching an example with simulated data below.

When changing the method to “relayout” the annotations change, but nothing else, as expected from the documentation. When I use “restyle”, the chart changes but not the annotation. “update” seems to have the same effect as “restyle”.

I’m working with Plotly v. 3.2.1. in Python 3.6.5 on Windows 10.

I am grateful for any suggestions.

### Importing packages

import numpy as np
import pandas as pd
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import plotly.graph_objs as go
import os

### Getting a list of the candidate countries

countries = ["Afghanistan", "Haiti", "Lebanon"]

### Preprocessing
xs = {}
ys = {}
Ns = {}

for country in countries:
    ys[country] = ["Safety", "Participation", "Empowerment"]
    xs[country] = np.random.uniform(1, 6, 3)
    Ns[country] = np.random.choice(np.arange(500, 1001))

### Adding convenience variables

annot_font = dict(family="Arial, sans-serif", size=15,
        color='#212F3D')
        
color_legend = False

Nfont =  dict(family="Arial, sans-serif", size=18, color='black')
        
bar_width = 0.6

### Update menu
buttons = []
for country in countries:
    option = dict(
            args=[dict(x = [xs[country]],
                       y = [ys[country]],
                       text = [np.round(xs[country], 2)],
                       annotations = [dict(text = str(Ns[country]),
                          font =  Nfont,
        showarrow = False,
        xref = 'paper', x = 0.95,
        yref = 'paper', y = 1)])],
            label=country,
            method='update'
        )
    buttons.append(option)

updatemenus=list([
    dict(
        buttons=list(buttons    
        ),
    direction = 'down',
    pad = {'r': 10, 't': 10},
    showactive = True,
    x = 0,
    xanchor = 'left',
    y = 1.1,
    yanchor = 'top' 
),
])

### axis parameters
xaxis=dict(
    autorange=True,
    showgrid=False,
    zeroline=True,
    showline=False,
    ticks='',
    showticklabels=False
)

yaxis = dict(
    automargin=True,
    ticks='outside',
    ticklen=8,
    tickwidth=4,
    tickcolor='#FFFFFF',
    tickfont=dict(
        family="Arial, sans-serif",
        size=15,
        color='black'))

### trace
trace = (go.Bar(y=ys["Afghanistan"], x=xs["Afghanistan"],
            text=np. round(xs["Afghanistan"], 2), textposition = 'inside',
            name="Mean Satisfaction", marker=dict(color='#03CEA3'),
            orientation="h", showlegend=color_legend,
            textfont=annot_font, hoverinfo = "name + text",
            width=bar_width))

### layout 
layout = go.Layout(barmode="stack", 
               xaxis=xaxis,
               yaxis=yaxis,
        annotations = [dict(text = str(Ns["Afghanistan"]),
                          font =  Nfont,
        showarrow = False,
        xref = 'paper', x = 0.95,
        yref = 'paper', y = 1)],
        updatemenus = updatemenus)
                          
fig = go.Figure(data=[trace], layout=layout)

Something like:

option = dict(
            args=[
              dict(
                 x = [xs[country]],
                 y = [ys[country]]
              ),
              dict(
                 annotations = [dict(
                    text = str(Ns[country]),
                    font =  Nfont,
                    showarrow = False,
                    xref = 'paper', x = 0.95,
                    yref = 'paper', y = 1)]
                )],
                label=country,
                method='update'
        )

should work. You need to split the data and layout updates into two separate dicts.

1 Like

That worked like a charm! Thank you so much for taking the time.

1 Like

Do you know how one would do this in JavaScript? I’ve got:

var layout = {
        updatemenus: [
            {
                type: "dropdown",
                direction: "down",
                active: -1,
                buttons: [
                    {
                        method: "restyle",
                        args: ["x", [6, 7, 7, 7, 8]],
                        label: "update_data",
                        name: ""
                    }
                ]
            }
        ]
    };

when I click “update_x” the existing plot disappears.

Got the answer from this stackoverflow answer to a similar question. I’ve changed

args: ["x", [6, 7, 7, 7, 8]]

to

args: [ "x", [[6, 7, 7, 7, 8]] ]

and that did the trick for me.