Problem with figure not updating dimensions when its parent container is resized

In my application I have a tab system containing a div that fits the rest of the screen that will most often display a 2x2 grid of charts. However sometimes there will be three or four columns instead of two and I have noticed some strange behaviour.

Image A

Image B

Image C

In the first image is a typical 2 by 2 grid that is the first tab loaded and it loads fine. However when I click on the second tab to load a 3 columns by 2 rows grid of charts the first two charts are at 50% width when they should be 33% and thus overflow. If you click on the same tab again it will load all the charts at 33% width as expected in the third image.

So the potential solutions I can see are:

  • How to force resizing of chart instead of manually resizing it by the user
  • Figure out how to ‘clear’ the figures before plotting a new figure underneath it since in the above pictures it looks as though figure dimensions are reused but not automatically recalculated according to the parent dimensions which are changed via CSS.

I have looked at similar questions but haven’t found a working solution.

I have a very basic sample application which sort of shows how I am achieving the grid layout, the style of the parent is changed according to button click. Also it is important in my application to use % for height and width specifically which is reflected in the example.

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = \
        html.Div(children=[
            html.Button('Resize parent', id='btn_resize'),
            html.Div([
                dcc.Graph(
                    id='example-graph',
                    figure={
                        'data': [
                            {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
                        ],
                        'layout': {
                            'paper_bgcolor': 'yellow',
                        }
                    },
                    style={'height': '100%', 'width': '100%'},
                    config={
                        'responsive': True, # Doesn't seem to help
                        'displayModeBar': True,
                    }
                )
            ], id='parent_container',
            ),
        ], style={'height': '100%', 'width': '100%'},)


@app.callback(
    [
        Output('parent_container', 'style'),
        Output('example-graph', 'figure'),
    ],
    [
        Input('btn_resize', 'n_clicks'),
    ],
)
def update_figure(n_clicks):
    if n_clicks:
        # So that the button toggles between the two parent container sizes
        if n_clicks % 2 == 1:
            figure = {
                         'data': [
                             {'x': [3, 2, 1], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                         ],
                         'layout': {
                             'paper_bgcolor': 'yellow',
                         }
                     },
            return [{'width': '75%', 'border': '2px solid red'}, figure[0]]
    figure = {
                 'data': [
                     {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
                 ],
                 'layout': {
                     'paper_bgcolor': 'yellow',
                 }
             },
    return [{'width': '50%', 'border': '2px solid red'}, figure[0]]


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

If you click the button to change the width of the parent then the figure won’t resize unless you resize the browser window. Interestingly I have kept the displayModeBar to always on to show that the dcc.Graph does change when the parent dimensions changes but not the figure.

have you tried upgrading to the latest dash? we just shipped some features that will enable better auto resizing in the graph. i believe the latest announcement has more details (i’m on my phone right now, otherwise i’d send the link!)

Hi, yes I was on dash 1.6.1 and upgrading to 1.8.0 fixed the issue in the sample provided. I should pay closer attention to version releases! Thanks.

edit: I should mention that the responsive = True in the sample code is now important in 1.8.0, leaving it out according to 1.8.0 would mean responsive = auto which does not give the intended responsive behaviour.

1 Like