Plotly: Add line to bar chart - python

I have a plotly bar chart, from a dataframe:
fig = df.iplot(asFigure=True, kind='bar', barmode = 'relative')
py.iplot(fig)
Is it possible to turn one of the columns in the data frame into a line series?

The suggested link in the comments does have some valuable resources, but they won't answer your questions directly. iplot() uses a pandas dataframe as input, and produces a stacked barplot. Here's an approach that will let you do exactly that, albeit without using df.iplot()
First, the plot :
Now, the code
My suggestion builds on an example found at: plot.ly/pandas/bar-charts. As you'll see that's an example that builds on a pandas dataframe - just like df.iplot(). You can simply take a series or 'trace' out of the stacked bars and display it as a line by changing
go.Bar(x=df['x'],
y=df['y4'])
to:
go.Scatter(x=df['x'],
y=df['y4'])
I've also added a few elements to make it easier to display your results offline in a Jupyter notebook. Also note that I've changed the last line from py.iplot(fig, filename='pandas-bar-chart-layout') to just iplot(fig, filename='pandas-bar-chart-layout')
Complete snippet:
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
import pandas as pd
import numpy as np
N = 20
x = np.linspace(1, 10, N)
y = np.random.randn(N)+3
y2 = np.random.randn(N)+6
y3 = np.random.randn(N)+9
y4 = np.random.randn(N)+12
df = pd.DataFrame({'x': x, 'y': y, 'y2':y2, 'y3':y3, 'y4':y4})
df.head()
data = [
go.Bar(
x=df['x'], # assign x as the dataframe column 'x'
y=df['y']
),
go.Bar(
x=df['x'],
y=df['y2']
),
go.Bar(
x=df['x'],
y=df['y3']
),
go.Scatter(
x=df['x'],
y=df['y4']
)
]
layout = go.Layout(
barmode='stack',
title='Stacked Bar with Pandas'
)
fig = go.Figure(data=data, layout=layout)
# IPython notebook
iplot(fig, filename='pandas-bar-chart-layout')

answering to the last comment, I changed the code to include a loop like you asked.
Let me know if this helps:
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
import pandas as pd
import numpy as np
N = 20
x = np.linspace(1, 10, N)
y = np.random.randn(N)+3
y2 = np.random.randn(N)+6
y3 = np.random.randn(N)+9
y4 = np.random.randn(N)+12
df = pd.DataFrame({'x': x, 'y': y, 'y2':y2, 'y3':y3, 'y4':y4})
df.head()
data = []
for i in df.columns:
if i!= "x":
data.append(
go.Bar(
x=df['x'], # assign x as the dataframe column 'x'
y=df[i]
)
)
layout = go.Layout(
barmode='stack',
title='Stacked Bar with Pandas'
)
fig = go.Figure(data=data, layout=layout)
# IPython notebook
iplot(fig, filename='pandas-bar-chart-layout')

Related

Plotly python add annotation to display all column values at every point

I am trying to plot all column values at each point when we hover over a data point in plotly
My code is as follows
import plotly.graph_objects as go
import plotly.io as pio
from plotly.subplots import make_subplots
import pandas as pd
# data
pio.templates.default = "plotly_white"
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
df_s = df[['Date','AAPL.Open','AAPL.High','AAPL.Low','dn','mavg'
]]
df_s = df_s.set_index('Date')
df_s.tail()
cols = df_s.columns
ncols = len(cols)
# subplot setup
fig = make_subplots(rows=ncols, cols=1, shared_xaxes=True)
for i, col in enumerate(cols, start=1):
fig.add_trace(go.Scatter(x=df_s[col].index, y=df_s[col].values, name=df_s[col].name), row=i, col=1)
fig.update_layout(
autosize=False,
width=1200,
height=800,)
fig.show()
Currently when I hover over the datapoint it shows value for that column alone. I am interested in seeing
Values for 'Date','AAPL.Open','AAPL.High','AAPL.Low','dn','mavg' these columns at a particular row whenever I hover over anyplot
I tried add_annotations with no luck. Is there a way of doing it? Thank you in advance
As #Marco_CH pointed out, this exact feature doesn't exist in Plotly. However, you can try using a unified hovermode on the x-axis so there is only one hoverbox, and remove the date from each hovertemplate since it's already shown at the top of the hoverbox.
import pandas as pd
import plotly.express as px
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
df1 = df.melt(id_vars=['Date']+list(df.keys()[5:]), var_name='AAPL')
fig = px.line(df1, x='Date', y='value', color='AAPL' )
## remove date from each hovertemplate
for fig_data in fig.data:
fig_data['hovertemplate'] = fig_data['hovertemplate'].replace("<br>Date=%{x}","")
fig.update_layout(hovermode="x unified")
fig.show()
No, this doesn't work. There is an open issue for this:
https://github.com/plotly/plotly.js/issues/4755
And it doesn't seem that this will come soon. You have to decide between your way and something like:
import pandas as pd
import plotly.express as px
pio.templates.default = "plotly_white"
df_s = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
df_s = df_s.melt(id_vars=["Date"]+list(df.keys()[5:]), var_name="AAPL")
fig = px.line(df_s, x="Date", y="value", color="AAPL")
fig.update_layout(
autosize=False,
width=1200,
height=800,
hovermode="x")
fig.show()
Output:

Plotly: How to plot multiple lines with shared x-axis?

I would like to have a multiple line plot within same canvas tied with the same x-axis as shown something in the figure:
Using subplots does not achieve the intended desire.
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig = make_subplots(rows=2, shared_xaxes=True,vertical_spacing=0.1)
fig.add_scatter(y=[2, 1, 3], row=1, col=1)
fig.add_scatter(y=[1, 3, 2], row=2, col=1)
fig.show()
May I know how this can be done, appreciate if someone can point to good reading material
With a dataset such as this you can select any number of columns, set up a figure using fig = make_subplots() with shared_xaxes set to True and then add your series with a shared x-axis using fig.add_trace(go.Scatter(x=df[col].index, y=df[col].values), row=i, col=1) in a loop to get this:
Let me know if this is a setup you can use but need a little tweaking.
Complete code:
import plotly.graph_objects as go
import plotly.io as pio
from plotly.subplots import make_subplots
import pandas as pd
# data
pio.templates.default = "plotly_white"
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
df = df.set_index('Date')
df.tail()
cols = df.columns[:-4]
ncols = len(cols)
# subplot setup
fig = make_subplots(rows=ncols, cols=1, shared_xaxes=True)
for i, col in enumerate(cols, start=1):
fig.add_trace(go.Scatter(x=df[col].index, y=df[col].values), row=i, col=1)
fig.show()
Depending on the data you are plotting, I think you could either check out "Stacked Subplots with a Shared X-Axis (low-level API)" on https://plotly.com/python/subplots/
Or separate the data by shifting each line plot upwards like so:
import plotly.graph_objects as go
import random
data = []
n = 9
for x in range(10, 60, 10):
points = [value + x for value in random.sample(range(1,n+1), k = n)]
data.append(go.Scatter(y=points))
fig = go.Figure(data = data)
fig.show()

Plotting multiple lines in plotly on the same graph using fig.show?

I have some old code that graphs lots of lines on the same graph in a manner like
import plotly.plotly as py
import plotly.graph_objs as go
data = [regtimes, avg5times]
py.iplot(data, filename='basic-line')
and this would graph both lines on the same plot. I tried to use this again and it says plotly.plotly is deprecated. Now I have something like
individualtimes = go.Scatter(
y = times,
x = x1,
)
test = go.Scatter(
y2=[1, 1, 5],
x2=x1
)
data = [individualtimes,test]
fig = go.Figure(data=data)
fig.show()
Is there a way to use fig.show to graph multiple lines like this? Thanks!
I have found the answer! It has been changes to use add_trace and then show the figure. Plotly uses
import plotly.graph_objects as go
# Create random data with numpy
import numpy as np
np.random.seed(1)
N = 100
random_x = np.linspace(0, 1, N)
random_y0 = np.random.randn(N) + 5
random_y1 = np.random.randn(N)
random_y2 = np.random.randn(N) - 5
# Create traces
fig = go.Figure()
fig.add_trace(go.Scatter(x=random_x, y=random_y0,
mode='lines',
name='lines'))
fig.add_trace(go.Scatter(x=random_x, y=random_y1,
mode='lines+markers',
name='lines+markers'))
fig.add_trace(go.Scatter(x=random_x, y=random_y2,
mode='markers', name='markers'))
fig.show()
The rest of this can be found here.

Error bar information not displaying in Scatter3d hover

I have a 3d plot working with z_axis asymmetrical error bars, but when I hover over the data points, I'm only getting the (x,y,z) information instead of (x,y,z +err/-err).
Plotly documentation for the error bars indicates that this information should be automatically included in the hover label. I tried using the hovertext attribute (setting hoverinfo='text' per the Scatter3d docs) with no success. Perhaps my attempt at reformatting labels isn't in the format that plotly requires, but I've tried a few different ways now to no avail. Below is the code trying to use the hovertext and hoverinfo attributes.
import pandas as pd
import numpy as np
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import iplot, init_notebook_mode
import cufflinks as cf
cf.go_offline()
cf.set_config_file(world_readable=True,theme='pearl',offline=True)
init_notebook_mode()
x = [1,2,3,4,5]
y = [1,2,3,4,5]
z1 = [1,2,3,4,5]
z2 = np.multiply(z1,2)
z3 = np.multiply(z1,0.5)
df = pd.DataFrame({'A':x,'B':y,'C':z1,'D':z2,'E':z3})
test = []
for row in df.values:
test.append('x:{}; y:{}; z={} +{}/-{}'.format(row[0],row[1],row[2],row[3],row[4]))
fig = go.Figure()
fig.add_trace(
go.Scatter3d(
x=x,
y=y,
z=z1,
# https://plot.ly/python/reference/#scatter3d-error_z
error_z = dict(
visible=True,
type='data',
array=np.subtract(z2,z1),
arrayminus=np.subtract(z1,z3)
),
name='Test Plot',
marker=dict(size=4),
opacity = 1, # 1=default
mode='markers',
hovertext=test,
hoverinfo='text' # set this to 'text' if using 'hovertext' attr
)
)
fig.layout.update(scene = dict(
xaxis_title='X Axis',
yaxis_title='Y Axis',
zaxis_title='Output')
)
fig.show()

Plotly: How to set the range of the y axis?

I have the following code to create the line plot with Plotly. How can I set the range of Y axis to always have it in [0; 10]?
layout = go.Layout(
title=go.layout.Title(
text="Test",
xref='paper',
x=0
),
xaxis=go.layout.XAxis(
tickmode='linear',
tickfont=dict(
size=10
),
title=go.layout.xaxis.Title(
font=dict(
size=14,
color='#7f7f7f'
)
)
),
yaxis=go.layout.YAxis(
title=go.layout.yaxis.Title(
text=y,
font=dict(
size=14,
color='#7f7f7f'
)
)
)
)
data = [go.Scatter(x=x1, y=y1)]
Update for newer versions
When setting up a figure you can use plotly's magic underscore notation and specify layout_yaxis_range=[<from_value>, <to_value>] like this:
fig = go.Figure(data=go.Scatter(x=x, y=y, mode='lines'), layout_yaxis_range=[-4,4])
Or if you've already got a figure named fig, you can use:
fig.update_layout(yaxis_range=[-4,4])
And:
fig.update(layout_yaxis_range = [-4,4])
Or:
fig.update_yaxes(range = [-4,4])
Figure:
Complete code:
# imports
import pandas as pd
import plotly.graph_objs as go
import numpy as np
# data
np.random.seed(4)
x = np.linspace(0, 1, 50)
y = np.cumsum(np.random.randn(50))
# plotly line chart
fig = go.Figure(data=go.Scatter(x=x, y=y, mode='lines'), layout_yaxis_range=[-4,4])
fig.update_layout(yaxis_range=[-4,4])
fig.show()
Original answer using plotly.offline, iplot and no magic underscore notation:
When setting up a figure, use:
layout = go.Layout(yaxis=dict(range=[fromValue, toValue])
Or if you've already got a figure named fig, you can use:
fig.update_layout(yaxis=dict(range=[fromValue,toValue]))
Plot:
Complete code for Jupyter Notebook:
# imports
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import pandas as pd
import plotly.graph_objs as go
import numpy as np
# setup
init_notebook_mode(connected=True)
# data
np.random.seed(4)
x = np.linspace(0, 1, 50)
y = np.cumsum(np.random.randn(50))
# line
trace = go.Scatter(
x=x,
y=y,
)
# layout
layout = go.Layout(yaxis=dict(range=[-4,4])
)
# Plot
fig = go.Figure(data=[trace], layout=layout)
iplot(fig)
Some important details:
With this setup, you can easily add an y axis title like this:
# layout
layout = go.Layout(yaxis=dict(range=[-4,4]), title='y Axis')
)
It's a little more tricky if you'd like to format that title further. I find it easiest to actually add another element with title = go.layout.yaxis.Title(text='y Axis', font=dict(size=14, color='#7f7f7f'). As long as you do it the right way, you should not experience the situation in your comment above:
Thanks. I tried it. But then I have 2 definitions of yaxis in the
Layout: yaxis=dict(range=[0, 10]) and yaxis=go.layout.YAxis. Therefore
an error appears.
Take a look at this:
Plot:
Complete code with y-axis text formatting:
# imports
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import pandas as pd
import plotly.graph_objs as go
import numpy as np
# setup
init_notebook_mode(connected=True)
# data
np.random.seed(4)
x = np.linspace(0, 1, 50)
y = np.cumsum(np.random.randn(50))
# line
trace = go.Scatter(
x=x,
y=y,
)
# layout
layout = go.Layout(
yaxis=dict(range=[-4,4],
title = go.layout.yaxis.Title(text='y Axis', font=dict(size=14, color='#7f7f7f')))
)
# Plot
fig = go.Figure(data=[trace], layout=layout)
iplot(fig)
If I understand you right you want to limit the range of the y-axis itself. You can pass a dict in the keyword argument yaxis. It could be something like go.Layout(yaxis=dict(range=[0, 10])) I hope this helps you.

Categories