Plotly: How to change the range of the y-axis of a subplot?

Question:

I have the following code:

from plotly.subplots import make_subplots
import requests 
import json
import datetime as dt
import pandas as pd
import plotly.graph_objects as go




def get_candles(symbol, window, interval='1h'):
    url = "https://api.binance.com/api/v1/klines"
    end_time = dt.datetime.utcnow()
    delta = dt.timedelta(hours = window)
    start_time = end_time - delta
    start_date = str(int(start_time.timestamp() * 1000))
    end_date = str(int(end_time.timestamp() * 1000))
    limit = '1000'
    market = symbol + 'BUSD'

    req_param = {"symbol": market, "interval": interval, "startTime": start_date, "endTime": end_date, "limit": limit}

    text = requests.get(url, params = req_param).text
    data = json.loads(text)
    df = pd.DataFrame(data)
    df.columns = ['open_time',
                    'o', 'h', 'l', 'c', 'v',
                    'close_time', 'qav', 'num_trades',
                    'taker_base_vol', 'taker_quote_vol', 'ignore']

    df.index = [dt.datetime.fromtimestamp(x/1000.0) for x in df.close_time]

    return df


def chart(symbol, interval='1h'):
    windows = {'1m': 1, '5m': 5, '15m': 15, '30m': 30, '1h': 60, '2h': 120, '4h': 240, '6h': 360, '12h': 720, '1d': 1440}
    chart = get_candles(symbol.upper(), windows[interval], interval)
    fig = make_subplots(specs=[[{"secondary_y": True}]])
    print(chart['v'].max())
    fig.add_trace(go.Candlestick(x=chart.index,
            open=chart['o'],
            high=chart['h'],
            low=chart['l'],
            close=chart['c'],
            name="yaxis1 data",
            yaxis='y1'), secondary_y=True)
    fig.add_trace(go.Bar(x=chart.index, y=chart['v'], name="yaxis2 data", yaxis="y2"), secondary_y=False)
    fig.layout.yaxis2.showgrid=False
    fig.update_yaxes(type="linear")
    fig.update_layout(xaxis_rangeslider_visible=False)
    
    # fig.show()

    fig.write_image("figure.png", engine="kaleido")
    
chart('bnb')

And it produces the following image:
Chart this code generates

Now I want it so that the volume bars go to only to 1/3 of the total height of the chart and I tried doing this like this:

fig.update_layout(yaxis1=dict(title="bars", domain=[0, int(2* chart['v'].max())]))

But this does nothing.

How do I give a certain y-axis a name and change the range of that?

Answers:

I don’t use plotly, but looking at the docs, I see the following for setting the range of the y-axis:

Code: fig.update_yaxes(range=<VALUE>)
Type: list

https://plotly.com/python/reference/layout/yaxis/#layout-xaxis-range

For a label/title:

Code: fig.update_yaxes(title=dict(...))
Type: dict containing one or more of the keys listed below.

fig.update_layout(title_text=<VALUE>)

https://plotly.com/python/reference/layout/yaxis/#layout-yaxis-title

Answered By: astrochun

This is the way:

fig.update_layout(yaxis2 = dict(range=[<from_value>, <to_value>]))

Your code sample does not work on my end. But in this example, the following setup:

fig.update_layout(yaxis2 = dict(range=[0, 300*10**6]))

… will turn this:

enter image description here

… into this:

enter image description here

Complete code:

import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd

# data
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')

# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])

# include candlestick with rangeselector
fig.add_trace(go.Candlestick(x=df['Date'],
                open=df['AAPL.Open'], high=df['AAPL.High'],
                low=df['AAPL.Low'], close=df['AAPL.Close']),
               secondary_y=False)

# include a go.Bar trace for volumes
fig.add_trace(go.Bar(x=df['Date'], y=df['AAPL.Volume']),
               secondary_y=True)
f = fig.full_figure_for_development(warn=False)

fig.layout.yaxis2.showgrid=False
fig.update_layout(yaxis2 = dict(range=[0, 300*10**6]))
fig.show()
Answered By: vestland

I had an issue similar to this but the answers above didn’t help as my chart is dynamic. Dependant on the timeframe the max volume can be anywhere from 300 – 10 million, so fixed ranges were no good.

It seemed that the best solution was to use the max() function to find the highest value in the volume column of my dataframe (also dynamic):

maxVol = max(df['Volume'], key=float)
ymax = float(maxVol)
print(ymax)

Then simply use the following to scale the max range by a factor of 3

fig.update_layout(yaxis=dict(range=[0, ymax*3]))
Answered By: Matthew Banham
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.