11

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?

0

3 Answers 3

15

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()
Sign up to request clarification or add additional context in comments.

Comments

1

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]))

Comments

-2

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

5 Comments

I know this, I read the docs as well. What I can't figure out is how to change 1 y-axis (I have 2).
Have you tried secondary_y = False or True? See: plotly.com/python/multiple-axes
fig contains both axes, so when updating, you still need to be explicit. Much like how you use add_trace, you need to specify secondary_y in your fig.update_yaxes
Thanks that's it
@MathijsvandenDoel, when I get a chance, I'll modify my answer so it's an acceptable answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.