One button for two methods?

I have an animated graph, where within a few frames, the points on the plot are above the range of the graph. I have one button that starts the animation, but at the same time that is running I would like to call the relayout method and have it autoscale the y-axis.

Is there a way to use one button to call multiple methods and do both together? Or are there other workarounds to having the layout change between frames? Thanks.

# Play & Pause & Autoscale
figure['layout']['updatemenus'] = [
    {
        'buttons': [
            {
                'args': [None, {'frame': {'duration': 300, 'redraw': False},
                         'fromcurrent': True, 'transition': {'duration': 400, 'easing': 'quadratic-in-out'}}],
                'label': 'Play',
                'method': 'animate'
            },
            {
                'args': [[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate',
                'transition': {'duration': 0}}],
                'label': 'Pause',
                'method': 'animate'
            },
            {
                'args': [{'yaxis.autorange': True}],
                'label': 'Autoscale',
                'method': 'relayout'
            },
        ],
        'direction': 'left',
        'pad': {'r': 10, 't': 87},
        'showactive': False,
        'type': 'buttons',
        'x': 0.1,
        'xanchor': 'right',
        'y': 0,
        'yanchor': 'top'
    }
]

Hi @album,
I’m not sure I understand what you’re trying to do. Are you trying to start with autorange off and then enable it for certain frames? If so, you might be able to add layout.yaxis.autorange=True to some of your frames.

Otherwise, could you add a full example that can be copied, pasted, and run?

-Jon

Hi @jmmease,

Yes, that’s exactly it. I’d like to have the autorange change with each frame. When I tried updating the figure.layout.yaxis at the bottom of the for loop, it seemed to have just kept the values for the final iteration of the loop. How can I add it such that each frame sets the layout with its own autorange?

Here’s my notebook for the code: https://nbviewer.jupyter.org/github/Album/Days-of-the-Week-of-each-Month-through-the-Years/blob/master/weekday-counter.ipynb

By the way, I saw your name pop up in another post about updating the y-range with an x-range slider. Thanks for lending a hand here as well!

I found this post by @empet where each frame has a dictionary of a new calculated yaxis range. I tried to replicate this by testing with a range of [0, year] for the corresponding year of the frame, but it still does not seem to be updating between frames.

# Updating frames
for year in yList:
    frame = {'data': [], 'name': str(year), 'layout':[]}
    for day in wList:
        data_dict = {
            'xsrc': countGrid.get_column_reference(col_name_template.format(
                year=year, weekday=day, header='month'
            )),
            'ysrc': countGrid.get_column_reference(col_name_template.format(
                year=year, weekday=day, header='count'
            )),
            'mode': 'markers',
            'textsrc': countGrid.get_column_reference(col_name_template.format(
                year=year, weekday=day, header='month'
                )),
            'marker': {
                'size': set_size,
                'symbol': symbol[day],
                'color': color[day],
                'opacity': set_opacity,
                'line': {'color': line_color[day], 'width': set_line_width },
                'gradient': {'color': gradient_color[day], 'type':'radial'}
            },
            'name': day,
        }
        frame['data'].append(data_dict)
        layout_dict = {
            'yaxis': {'range': [0, int(year)]}
        }
        frame['layout'].append(layout_dict)

    figure['frames'].append(frame)

I had also set the initial yaxis conditions to have autorange=False as suggested. And tried both with or without a default range [0,450]:

figure['layout']['yaxis'] = {'title': 'Days Counted', 'type': 'lin', 'range': [0, 450], 'gridcolor': '#FFFFFF', 'autorange':False}