✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚾️ It's finally Baseball season! Root for the home team... & Register for our Sports Analytics Webinar!

Best callback design to change only either data or layout in plotly figure

Let’s say I want to switch yscale.type between log and linear (this is, a layout attribute). Also I want to retrieve some attribute info in the data attribute of the figure. In the end, I’m only updating the layout though.

May I say, I’ve tried updatemenus but I don’t like the fact that every time I re-render the chart it goes back to the linear default.

All in all, I’m confused as to whether the either figure, data or layout become dictionaries or retain the go object status as they travel through callbacks.

    Output('chart', 'layout'),
      Input('log_checkbox', 'value'),
      [State('chart', 'figure')] )
def updateScale(log,figure ):  
    prices = figure.data[0].y
    if len(log) ==1:
        figure.layout.yaxis1 = dict(type = 'log',
        range=[ np.log10( prices.min() ) ,np.log10( prices.max()) ])    

        figure.layout.yaxis1 = dict(type = 'linear',
        range=[ prices.min()  , prices.max() ])          

    return figure.layout

This attempt yields:

AttributeError: ‘dict’ object has no attribute 'data

I’ve tried many more alternatives to no avail, all returning other errors such as “updatescale() takes 2 positional arguments but 4 were given” when I convert objects to plotly’s go format and use update_yaxes and updatelayout methods. Anyway, I’m sure many of you can quickly guide me on what the best practice is.


Note: As weid as it looks, the np.log10( prices.max()) approach works just fine in another callback. It’s necessary to recalculate the yaxis range every time I switch from log to linear scale.