# Pre-defined range buttons

**URL:** <https://community.plotly.com/t/pre-defined-range-buttons/39267>\
**Category:** 📊 Plotly Python\
**Created:** [May 12, 2020, 1:36am UTC](https://community.plotly.com/t/pre-defined-range-buttons/39267 "2020-05-12T01:36:12Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![tjf2007](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/tjf2007/32/10755_2.png) [@tjf2007](https://community.plotly.com/u/tjf2007)\
**Post date:** [May 12, 2020, 1:36am UTC](https://community.plotly.com/t/pre-defined-range-buttons/39267/1 "2020-05-12T01:36:12Z")

</div>

How can I set rangeselector() buttons to zoom in on pre-defined date ranges for a time series plot? For example, I’m looking at stock market data for 2020 YTD, and I’d like to have two buttons “The Bull Run” and “the Crash”, which refer to the datetime ranege Bullrun=[2020-01-03 to 2020-02-19] and Crash=[2020-02-20 - 2020-05-06], and when I click on those buttons (instead of it being say “Last 6mo” or “YTD”), i want the plot to zoom in on those time periods specifically. Thank you.

---

<div class="post-metadata">

**Author:** ![Emmanuelle](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/emmanuelle/32/7853_2.png) [@Emmanuelle](https://community.plotly.com/u/Emmanuelle)\
**Post date:** [May 12, 2020, 8:00am UTC](https://community.plotly.com/t/pre-defined-range-buttons/39267/2 "2020-05-12T08:00:38Z")

</div>

Hi @tjf2007 welcome to the forum! For this you can use a normal layout button which modifies the xaxis range, like in the example below. For more details please refer to [the tutorial on layout buttons](https://plotly.com/python/custom-buttons/)

```auto
import plotly.graph_objects as go

import pandas as pd

# Load data
df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
df.columns = [col.replace("AAPL.", "") for col in df.columns]

# Create figure
fig = go.Figure()

fig.add_trace(
    go.Scatter(x=list(df.Date), y=list(df.High)))

# Set title
fig.update_layout(
    title_text="Time series with range slider and selectors"
)

# Add range slider
fig.update_layout(
    xaxis=dict(
       
        rangeslider=dict(
            visible=True
        ),
        type="date",
        range=('2015-04-01', '2017-01-01')
    )
)
fig.update_layout(
    updatemenus=[
        dict(
            type="buttons",
            buttons=[
                dict(label="Custom",
                     method="relayout",
                     args=["xaxis", {'range':('2015-07-01', '2015-09-01'),
                                    'rangeslider':dict(visible=True),}]),]
        )]
)
fig.show()

```

Note that with the button your modifying all xaxis attributes so if you want some of them to persist (as with the rangeslider) you need to pass them along in the `args`.

---

<div class="post-metadata">

**Author:** ![Emmanuelle](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/emmanuelle/32/7853_2.png) [@Emmanuelle](https://community.plotly.com/u/Emmanuelle)\
**Post date:** [May 12, 2020, 8:02am UTC](https://community.plotly.com/t/pre-defined-range-buttons/39267/3 "2020-05-12T08:02:18Z")

</div>

In fact a simpler syntax is to pass directly `xaxis.range` in the `args` as in

```auto
import plotly.graph_objects as go

import pandas as pd

# Load data
df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
df.columns = [col.replace("AAPL.", "") for col in df.columns]

# Create figure
fig = go.Figure()

fig.add_trace(
    go.Scatter(x=list(df.Date), y=list(df.High)))

# Set title
fig.update_layout(
    title_text="Time series with range slider and selectors"
)

# Add range slider
fig.update_layout(
    xaxis=dict(
       
        rangeslider=dict(
            visible=True
        ),
        type="date",
        range=('2015-04-01', '2017-01-01')
    )
)
fig.update_layout(
    updatemenus=[
        dict(
            type="buttons",
            buttons=[
                dict(label="Custom",
                     method="relayout",
                     args=["xaxis.range", ('2015-07-01', '2015-09-01'),]),]
        )]
)
fig.show()

```

---

<div class="post-metadata">

**Author:** ![GallopingNarwhal](https://avatars.discourse-cdn.com/v4/letter/g/bbce88/32.png) [@GallopingNarwhal](https://community.plotly.com/u/GallopingNarwhal)\
**Post date:** [August 14, 2023, 6:52pm UTC](https://community.plotly.com/t/pre-defined-range-buttons/39267/4 "2023-08-14T18:52:50Z")

</div>

I’m working on something similar, where I want to add a button that toggles on/off my hard-coded ylimits. In particular, I want args2 to revert the y range back to what was automatically set by plotly (based off the data). I found some odd behavior (and a toggle solution) that I wanted to document here in case it helps others.

My first attempt overwrote other aspects of the axis since I was setting the whole dictionary (like Emmanuelle mentions). This wasn’t the desired behavior; however, args2 (the second click on the button) successfully resets the axis to the original range ~(0, 100).

```auto
import pandas as pd
import numpy as np
import plotly.express as px

# Create Dataframe and Figure
y = list(np.random.randint(0, 10, size=49)) + [100]
x = list(range(0,50))
df = pd.DataFrame(index=x, data=y)
fig = px.line(df)
# Create Button
yrange = [0, 11]
buttons = [dict(args=["yaxis", {"range": yrange}],
                args2=["yaxis", {"range": 'auto'}],
                label="Toggle Y range",
                method='relayout')]
# Create menu and update layout
um = [dict(buttons=buttons, type='buttons', active=-1)]
fig.update_layout(updatemenus=um)
fig.show()

```

My second attempt - after seeing this thread - used “yaxis.range” to maintain all other aspects of the yaxis. My new button code was:

```auto
buttons = [dict(args=["yaxis.range", yrange],
                args2=["yaxis.range", 'auto'],
                label="Toggle Y range",
                method='relayout')]

```

This however did not revert the y-axis to (0, 100), but instead changed it to ~(-1, 4) on the second click (aka using args2). I had guessed on the “auto” keyword, and assumed it was correct since the first method of overwriting the dictionary worked. However, in [the documentation](https://plotly.com/python/reference/layout/yaxis/), I didn’t find “auto” as an option. Note: the -1, 4 is also the default y limits with an empty Figure.

In my 3rd attempt, I set args2 to update yaxis.autorange (which I was hoping would override the range). It worked as desired; here’s the full example code for toggling a hard-coded y limit:

```auto
import pandas as pd
import numpy as np
import plotly.express as px

# Create Dataframe and Figure
y = list(np.random.randint(0, 10, size=49)) + [100]
x = list(range(0,50))
df = pd.DataFrame(index=x, data=y)
fig = px.line(df)
# Create Button
yrange = [0, 11]
# Method 3: Doesn't reset the range, but rather sets autorange to True
buttons = [dict(args=["yaxis.range", yrange],
                args2=["yaxis.autorange", True],
                label="Toggle Y range",
                method='relayout')]
# Create menu and update layout
um = [dict(buttons=buttons, type='buttons', active=-1)]
fig.update_layout(updatemenus=um)
fig.show()

```

I’m guessing that “auto” is an invalid value for yaxis.range. I’d love to understand why one method fell back to (essentially) autorange=True, and the other method fell back to (hard-coded?) default of (-1,4).
