Plotly yaxis2 manual scaling - python

I have a plotly-dash dashboard and I can't seem to rescale my secondary y-axis. Is there a way of doing this?
I've tried messing with the domain parameter and the range parameter in the go.Layout.
I need the volume bar chart to be scaled down and occupy maybe 10% of the height of the plot so it doesn't overlap with my candlesticks.
Thank you very much.
Any help is appreciated.
import pandas as pd
import pandas_datareader.data as web
import plotly.offline as pyo
import plotly.graph_objs as go
stock_ticker='AAPL'
start_date='2019-04-01'
end_date='2019-05-22'
data=[]
hist_stock_df = web.DataReader(stock_ticker,'iex',start_date, end_date)
data.append(go.Candlestick(x=hist_stock_df.index,
open=hist_stock_df['open'],
high=hist_stock_df['high'],
low=hist_stock_df['low'],
close=hist_stock_df['close'],
name='AAPL'))
data.append(go.Bar(x=hist_stock_df.index,
y=hist_stock_df['volume'].values,
yaxis='y2'))
#y0=1000000
layout=go.Layout(title= 'Candestick Chart of AAPL',
xaxis=dict(title='Date',rangeslider=dict(visible=False)),
yaxis=dict(title='Price'),
plot_bgcolor='#9b9b9b',
paper_bgcolor='#9b9b9b',
font=dict(color='#c4c4c4'),
yaxis2=dict(title='Volume',
overlaying='y',
side='right'))
#scaleanchor='y'))
#scaleratio=0.00000001,
#rangemode='tozero',
#constraintoward='bottom',
#domain=[0,0.1]))
fig = go.Figure(data=data, layout=layout)
pyo.iplot(fig)
I have tried messing with the commented parameters
UPDATE
With this combination of layout parameters I managed to rescale the bars, but now there are two x-axis, been trying to figure out how to bring the middle x-axis down.
layout=go.Layout(title= 'Candestick Chart of AAPL',
xaxis=dict(title='Date',rangeslider=dict(visible=False)),
yaxis=dict(title='Price'),
plot_bgcolor='#9b9b9b',
paper_bgcolor='#9b9b9b',
font=dict(color='#c4c4c4'),
yaxis2=dict(title='Volume',
overlaying='y',
side='right',
scaleanchor='y',
scaleratio=0.0000001))

Use secondary_y=True or secondary_y=False within fig.update_yaxes() to specify which axis to adjust.
Plot 1: Without manual adjustments
Plot 2: With manual adjustments
Code:
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import datetime
# data
np.random.seed(1234)
numdays=20
dates = pd.date_range('1/1/2020', periods=numdays)
A = (np.random.randint(low=-10, high=10, size=numdays).cumsum()+100).tolist()
B = (np.random.randint(low=0, high=100, size=numdays).tolist())
df = pd.DataFrame({'A': A,'B':B}, index=dates)
# plotly figure setup
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Scatter(name='A', x=df.index, y=df['A'].values))
fig.add_trace(go.Bar(name='B', x=df.index, y=df['B'].values), secondary_y=True)
# plotly manual axis adjustments
fig.update_yaxes(range=[50,160], secondary_y=False)
fig.update_yaxes(range=[-10,200], secondary_y=True)
fig.show()

Related

How to add a secondary Y axis to a Plotly Express bar plot?

I would like to add a second Y axis to my bar plot bellow, that is the number of citizens in integer:
this graph was made using plotly:
import plotly.express as px
fig = px.bar(df, x="country",y="pourcent_visit",color="city",barmode='group')
# fig.add_hline(y=10)
fig.show()
To my knowledge, there's no direct way to do this. But you can easily build a Plotly Express figure, grab the traces (and data structures) from there and combine them in a figure that allows multiple axes using fig = make_subplots(specs=[[{"secondary_y": True}]]). With no provided data sample, I'll use the built-in dataset px.data.tips() that I'm guessing to a large part resembles the structure of your real world dataset judging by the way you've applied the arguments in px.bar(). Details in the comments, but please don't hesitate to let me know if something is unclear.
Plot:
Complete code:
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# sample data
df = px.data.tips()
# figure setup with multiple axes
fig = make_subplots(specs=[[{"secondary_y": True}]])
# build plotly express plot
fig2 = px.bar(df, x="day", y="total_bill", color="smoker", barmode="group")
# add traces from plotly express figure to first figure
for t in fig2.select_traces():
fig.add_trace(t, secondary_y = False)
# handle data for secondary axis
df2 = df.groupby('day').agg('sum')#.reset_index()
df2 = df2.reindex(index = df['day'].unique()).reset_index()
#
fig.add_trace(go.Scatter(x = df2['day'], y = df2['size'], mode = 'lines'), secondary_y = True)
# fix layout
fig.update_layout(legend_title_text = 'smoker')
fig.show()

Plotly align two Y-axis with different values

Is it possible to align two Y-axis by two different values? I would like to align my yaxis1 at zero with my yaxis2 at 1, like in the picture
picture
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
df = pd.DataFrame(dict(months=['jan','feb','mar','apr','may','jun'],
assets = [60,20,-25,-35,20,80],
liabilities = [70,75,80,90,70,50]))
# calculate ratio
df['ratio'] = df['assets'] / df['liabilities']
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Bar(x=df['months'], y=df['assets'], marker_color='green'))
fig.add_trace(go.Bar(x=df['months'], y=df['liabilities'], marker_color='red'))
fig.add_trace(go.Scatter(x=df['months'], y=df['ratio'], marker_color='orange'), secondary_y=True)
fig.update_yaxes(showgrid=False, secondary_y=True)
fig.show()
To set the range of the 2nd y-axis, set the range in the layout. The manual adjustment of the second y-axis affected the scale of the first y-axis, which was corrected at the same time. If it is not the intended scale, you are responsible for correcting it.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
df = pd.DataFrame(dict(months=['jan','feb','mar','apr','may','jun'],
assets = [60,20,-25,-35,20,80],
liabilities = [70,75,80,90,70,50]))
# calculate ratio
df['ratio'] = df['assets'] / df['liabilities']
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Bar(x=df['months'], y=df['assets'], marker_color='green',name='assets'))
fig.add_trace(go.Bar(x=df['months'], y=df['liabilities'], marker_color='red',name='liabilities'))
fig.add_trace(go.Scatter(x=df['months'], y=df['ratio'], marker_color='orange',name='ratio'), secondary_y=True)
fig.update_yaxes(showgrid=False, secondary_y=True),
fig.update_layout(autosize=True, yaxis=dict(range=[-50,150]), yaxis2=dict(range=[0,4]))#height=600,
fig.show()

Plotting bars with 5 min interval and adding a line

I am trying to plot closing price with positive and negative sentiment. I was able to plot it as the picture below; however, the colors are not showing properly for the bar chart. Any ideas how to change them?
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig2 = make_subplots(specs=[[{"secondary_y": True}]])
fig2.add_trace(go.Scatter(x=data.index,y=data['close'],name='Price'),secondary_y=False)
fig2.add_trace(go.Bar(x=data.index,y=data['pos'],name='Positive'),secondary_y=True)
fig2.add_trace(go.Bar(x=data.index,y=data['neg'],name='Negative'),secondary_y=True)
fig2.show()
have implied you dataframe structure from your code and used plotly finance sample data set as starting point
two things to look at wrt to layout
make Close trace the primary trace at front
review bargroup parameter and reduce bargap to zero
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv"
)
# make plotly dataset compatible with OP implied structure
data = df.set_index(pd.date_range("1-Jan-2022", freq="5Min", periods=len(df))).rename(
columns={"AAPL.Close": "close", "dn": "neg", "up": "pos"}
)
fig2 = make_subplots(specs=[[{"secondary_y": True}]])
fig2.add_trace(
go.Scatter(x=data.index, y=data["close"], name="Price"), secondary_y=False
)
fig2.add_trace(go.Bar(x=data.index, y=data["pos"], name="Positive"), secondary_y=True)
fig2.add_trace(go.Bar(x=data.index, y=data["neg"], name="Negative"), secondary_y=True)
# a few changes to make layout work better
# 1. put close at front
# 2. reduce "whitespace" in bars
fig2.update_layout(
yaxis={"overlaying": "y2"}, yaxis2={"overlaying": None}, barmode="overlay", bargap=0
)

Plotly: How to plot histogram in Root style showing only the contours of the histogram?

I want to make a histogram with this style:
But using plotly in Python. I.e. I want to merge the bars and plot only the contour. I am using this code:
import plotly.graph_objects as go
import numpy as np
x = np.random.randn(500)
fig = go.Figure(data=[go.Histogram(x=x)])
fig.show()
I have been looking for examples on how to do this but could not find any.
Your best option is to handle the histogram with numpy like count, index = np.histogram(df['data'], bins=25) , and then use go.Scatter() and set the linetype to horizontal, vertical, horizontal with line=dict(width = 1, shape='hvh'). Take a look at the very last section why go.Histogram() will not be your best option. With a few other specifications for the layout of go.Scatter(), the snippet below will produce the following plot:
Complete code
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import plotly.io as pio
import plotly.express as px
pio.templates.default = "plotly_white"
# random numbers to a df
np.random.seed(12)
df = pd.DataFrame({'data': np.random.randn(500)})
# produce histogram data wiht numpy
count, index = np.histogram(df['data'], bins=25)
# plotly, go.Scatter with line shape set to 'hvh'
fig = go.Figure()
fig.add_traces(go.Scatter(x=index, y = count,
line=dict(width = 1, shape='hvh')))
# y-axis cosmetics
fig.update_yaxes(
showgrid=False,
ticks="inside",
tickson="boundaries",
ticklen=10,
showline=True,
linewidth=1,
linecolor='black',
mirror=True,
zeroline=False)
# x-axis cosmetics
fig.update_xaxes(
showgrid=False,
ticks="inside",
tickson="boundaries",
ticklen=10,
showline=True,
linewidth=1,
linecolor='black',
mirror=True,
zeroline=False)
fig.show()
Why go.Scatter() and not go.Histogram()?
The closest you'll get to your desired plot using your approach with fig = go.Figure(data=[go.Histogram(x=x)]) is this:
And that's pretty close, but you specifically wanted to exclude the vertical lines for each "bar". And I have yet not found a way to exclude or hide them with the go.Histogram setup.
Code for go.Histogram()
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import plotly.io as pio
import plotly.express as px
pio.templates.default = "plotly_white"
import numpy as np
x = np.random.randn(500)
fig = go.Figure(data=[go.Histogram(x=x)])
fig.update_traces(marker=dict(color='rgba(0,0,0,0)', line=dict(width=1, color='blue')))
fig.show()
for a variation plotly.go.Histogram(): Show only horizontal lines of distribution. Plot just the lines
using pandas instead of numpy to build data for histogram then plotting as a line scatter
import plotly.graph_objects as go
import numpy as np
import pandas as pd
x = np.random.randn(100)
# build data frame that is histogram
df = pd.cut(x, bins=10).value_counts().to_frame().assign(
l=lambda d: pd.IntervalIndex(d.index).left,
r=lambda d: pd.IntervalIndex(d.index).right,
).sort_values(["l","r"]).rename(columns={0:"y"}).astype(float)
# lines in plotly are delimited by none
def line_array(df, cols):
return np.pad(
df.loc[:, cols].values, [(0, 0), (0, 1)], constant_values=None
).reshape(1, (len(df) * 3))[0]
# plot just lines
go.Figure(go.Scatter(x=line_array(df, ["l","r"]), y=line_array(df, ["y","y"]), marker={"color":"black"}))

Plotly doesn't draw barchart from pivot

I am trying to draw a bar chart from the CSV data I transform using pivot_table. The bar chart should have the count on the y-axis and companystatus along the x-axis.
I am getting this instead:
Ultimately, I want to stack the bar by CompanySizeId.
I have been following this video.
import plotly.graph_objects as go
import plotly.offline as pyo
import pandas as pd
countcompany = pd.read_csv(
'https://raw.githubusercontent.com/redbeardcr/Plotly/master/Data/countcompany.csv')
df = pd.pivot_table(countcompany, index='CompanyStatusLabel',
values='n', aggfunc=sum)
print(df)
data = [go.Bar(
x=df.index,
y=df.values,
)]
layout = go.Layout(title='Title')
fig = go.Figure(data=data, layout=layout)
pyo.plot(fig)
Code can be found here
Thanks for any help
If you flatten the array with the y values, i.e. if you replace y=df.values with y=df.values.flatten(), your code will work as expected.
import plotly.graph_objects as go
import plotly.offline as pyo
import pandas as pd
countcompany = pd.read_csv('https://raw.githubusercontent.com/redbeardcr/Plotly/master/Data/countcompany.csv')
df = pd.pivot_table(countcompany, index='CompanyStatusLabel', values='n', aggfunc=sum)
data = [go.Bar(
x=df.index,
y=df.values.flatten(),
)]
layout = go.Layout(title='Title')
fig = go.Figure(data=data, layout=layout)
pyo.plot(fig)

Categories

Resources