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

dcc.Graph floating toolbar blocks dcc.Dropdown on screen

If a dcc.Dropdown is placed above a dcc.Graph with a floating toolbar and the dropdown is selected to reveal the options, the floating toolbar stays in the forefront making it difficult to select an option.

For an example, see the graphical output under the “Update Graphs on Hover” section here: https://dash.plot.ly/interactive-graphing

Users have to search for a sweet spot on the dropdown so as not to click items on the toolbar. It would be great if the toolbar is sent to the background when dropdown options are shown.

Please let me know if I should introduce this as a feature request in the github repo.

If you don’t want the modebar you can use:

   dcc.Graph(...,
              config={'displayModeBar': False}
             )

I went to the page you linked and have no problem selecting in the dropdown. I am not sure why you find it difficult to select.

I’m aware of the config property but I don’t want to hide the displayModeBar as it is useful in my application.

To be more specific of my issue, run the example code below and try to use the right dcc.Dropdown to select the “Column 0” option for the Y-Axis. You should see that the floating displayModeBar stays in the forefront and blocks access to the “Column 0” option.

import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
import pandas as pd
from dash.dependencies import Input, Output, State


external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
server = app.server
app.config['suppress_callback_exceptions']=True

np.random.seed(0)
df = pd.DataFrame({
    'Column {}'.format(i): np.random.rand(30) + i*10
    for i in range(6)})


app.layout = html.Div([
    html.Div('dum', id='dum', style={'display': 'none'}),

    html.Div([
        html.Div(id='scat_a_x_drpdwn_div', style={'width': '16%', 'display': 'inline-block'}),
        html.Div(id='scat_a_y_drpdwn_div', style={'width': '16%', 'display': 'inline-block'})
    ],
        style={'width': '96%', 'margin': '0 auto'}),


    html.Div([
        html.Div(id='scat_a_div', style={'width': '32%', 'display': 'inline-block'})
    ], style={'width': '96%', 'margin': '0 auto'})
])

@app.callback(Output('scat_a_x_drpdwn_div', 'children'),
              [Input('dum', 'id')])
def show_scat_a_x_drpdwn(dum_id):
    if not dum_id: return

    return [
        html.Label('X-Axis:', style={'fontWeight': 'bold', 'textAlign': 'center'}),
        dcc.Dropdown(
            id='scat_a_x_drpdwn',
            options=[{'label': i, 'value': i} for i in df.columns],
            value=df.columns[0],
            style={'width': '100%', 'margin': '0 auto'}
        )
    ]

@app.callback(Output('scat_a_y_drpdwn_div', 'children'),
              [Input('dum', 'id')])
def show_scat_a_y_drpdwn(dum_id):
    if not dum_id: return

    return [
        html.Label('Y Axis:', style={'font-weight': 'bold', 'textAlign': 'center'}),
        dcc.Dropdown(
            id='scat_a_y_drpdwn',
            options=[{'label': i, 'value': i} for i in df.columns],
            value=df.columns[1],
            style={'width': '100%', 'margin': '0 auto'}
        )
    ]

#***SHOW SCATTER PLOTS CALLBACKS***

@app.callback(Output('scat_a_div', 'children'),
              [Input('dum', 'id')])
def show_scat_a(dum_id):
    if not dum_id: return

    return dcc.Graph(id='scat_a', figure=get_figure(df.columns[0], df.columns[1]))


@app.callback(Output('scat_a', 'figure'),
              [Input('scat_a_x_drpdwn', 'value'), Input('scat_a_y_drpdwn', 'value')],
              [State('scat_a', 'figure')])
def update_scat_a(x, y, figure):
    if not figure: return

    figure['data'][0]['x'] = df[x]
    figure['data'][0]['y'] = df[y]
    figure['layout']['xaxis']['title'] = x
    figure['layout']['yaxis']['title'] = y

    return figure



def get_figure(x, y):

    figure = {
        'data': [
            {
                'x': df[x],
                'y': df[y],
                'text': df.index,
                'textposition': 'top',
                'customdata': df.index,
                'hoverinfo': 'text',
                'type': 'scatter',
                'mode': 'markers+text',
                'marker': {
                    'color': 'rgba(0, 116, 217, 0.7)',
                    'size': 12,
                    'line': {
                        'color': 'rgb(0, 116, 217)',
                        'width': 0.5
                    }
                },
                'textfont': {
                    'color': 'rgba(30, 30, 30, 1)'
                },
                'unselected': {
                    'marker': {
                        'opacity': 0.3,
                    },
                    'textfont': {
                        # make text transparent when not selected
                        'color': 'rgba(0, 0, 0, 0)'
                    }
                }
            },
        ],
        'layout': {
            'margin': {'l': 50, 'r': 0, 'b': 50, 't': 30},
            'dragmode': 'select',
            'hovermode': 'closest',
            'showlegend': False,
            'xaxis': {'title': x},
            'yaxis': {'title': y}
        }
    }
    return figure

if __name__ == '__main__':
    app.run_server(debug=True)