Related
I'm new in using plotly and I'm trying to make a 2 different graph and show them individually through button; however, when I make it, the legends duplicated, resulting to a bad visualization of the data. Here's the code that I'm running right now:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly as ply
import plotly.express as px
import plotly.graph_objects as go
url = "https://raw.githubusercontent.com/m23chaffee/DS100-Repository/main/Aluminum%20Alloy%20Data%20Set.csv"
alloy = pd.read_csv('https://raw.githubusercontent.com/m23chaffee/DS100-Repository/main/Aluminum%20Alloy%20Data%20Set.csv')
del alloy['temper']
alloy = alloy.rename(columns={'aluminum_alloy':'Alloy Number',
'modulus_elastic': 'Elastic Modulus',
'modulus_shear': 'Shear Modulus',
'strength_yield': 'Yield Strength',
'strength_tensile': 'Tensile Strength'
})
bar1 = px.bar(alloy,
x = "Alloy Number",
y = ["Elastic Modulus", "Shear Modulus","Yield Strength","Tensile Strength"],
barmode = 'group',
width = 1100,
height =500,
orientation = 'v',
color_discrete_sequence = px.colors.qualitative.Pastel,
labels={"value": "Data Values"},
template = 'seaborn').update_traces(legendgroup="group").update_layout(showlegend=False)
line1 = px.line(alloy,
x = "Alloy Number",
y = ["Elastic Modulus", "Shear Modulus","Yield Strength","Tensile Strength"],
width = 1100,
height =500,
orientation = 'v',
color_discrete_sequence = px.colors.qualitative.Pastel,
labels={"value": "Data Values"},
template = 'seaborn').update_traces(legendgroup="group", visible = 'legendonly').update_layout(showlegend=False)
# Add buttom
fig.update_layout(
updatemenus=[
dict(
type = "buttons",
direction = "left",
buttons=list([
dict(
args=['type', 'bar'],
label="Bar Graph",
method="restyle",
),
dict(
args=["type", "line"],
label="Line Graph",
method="restyle"
)
]),
pad={"r": 10, "t": 10},
showactive=True,
x=0.11,
xanchor="left",
y=1.1,
yanchor="middle"
),
]
)
fig.show()
and the result of the image would look like this:
Result of the code above
Attempted Solution
I tried to hide it using traces and in the documentation but it seems it didn't work out for me. I also found a similar stackoverflow post 8 years ago, tried it, and it didn't make any changes in my graph.
I want to merge two stacked bar plot in plotly.express.
The code of the first figure is:
import pandas as pd
import plotly.express as px
from plotly.subplots import make_subplots
rscu1 = pd.read_csv("JQ038231.1_RSCU_stack.csv")
rscu2 = pd.read_csv("MG970255.1_RSCU_stack.csv")
rscu = pd.concat([rscu1, rscu2], keys=["JQ038231", "MG970255"])
rscu["species"] = rscu.index.get_level_values(0)
rscu = rscu.astype({"Fill": "category"})
rscu = rscu.astype({"aaRatio": "object"})
fig = px.bar(rscu, x="AA", y="RSCU", color="Fill", barmode = 'stack', text="aaRatio",
hover_data=['AA', "RSCU"], facet_row="species",
color_discrete_map={1: "#6598c9", 2: "#cb4a28", 3: "#9ac664", 4: "#7f5499"})
fig.update_xaxes(tickangle=0, title=None, ticks="outside")
fig.update_layout(
autosize=False,
width=950,
height=450,
showlegend=False)
for data in fig.data:
data["width"] = 0.9
fig.update_traces(textposition='outside')
fig.update_layout(uniformtext_minsize=8, uniformtext_mode='show')
These codes generate this figure:
The code of the second figure is:
fig_bottom = px.bar(rscu1, x="AA", y="Equality", color="Fill", barmode = 'stack', text="AA",
hover_data=['AA'], height=220, width=950,
color_discrete_map={1: "#6598c9", 2: "#cb4a28", 3: "#9ac664", 4: "#7f5499"})
fig_bottom.update_traces(textposition='inside', textfont_size=14)
fig_bottom.update_layout(uniformtext_minsize=9, uniformtext_mode='show', showlegend=False,)
fig_bottom.update_layout({"plot_bgcolor": "rgba(0, 0, 0, 0)",
"paper_bgcolor": "rgba(0, 0, 0, 0)"})
fig_bottom.update_yaxes(title=None, showticklabels=False)
fig_bottom.update_xaxes(title=None, showticklabels=False)
for data in fig_bottom.data:
data["width"] = 0.9
These codes generate this figure:
Is there a way to merge them into one figure, the final figure (made by ggplot) is:
The data used here can be found in https://github.com/dongzhang0725/sample_data
Updated
As per previous answer you can make_subplots(), add_trace() and finally update_layout()
source from GitHub
import requests
import io
rscu1 = pd.read_csv(io.StringIO(requests.get("https://raw.githubusercontent.com/dongzhang0725/sample_data/main/JQ038231.1_RSCU_stack.csv").text))
rscu2 = pd.read_csv(io.StringIO(requests.get("https://raw.githubusercontent.com/dongzhang0725/sample_data/main/MG970255.1_RSCU_stack.csv").text))
solution
# want "bottom" figure to use it's own axis to add to subplots
fig_bottom.data[0]["xaxis"]="x3"
fig_bottom.data[0]["yaxis"]="y3"
# subplots figure...
figall = make_subplots(rows=3, row_heights=[.4,.4,.2])
# add all the traces to appropriate subplot
for f in fig.data:
if f["yaxis"] == "y":
figall.add_trace(f, row=1, col=1)
else:
figall.add_trace(f, row=2, col=1)
figall.add_trace(fig_bottom.data[0], row=3, col=1)
# copy / modify layout of subplots figure
figall.update_layout(fig.layout)
fh = .38 # height of first two charts
figall.update_layout(
yaxis={"domain":[(1-2*fh)-.03,(1-fh)-.03]},
yaxis2={"domain":[1-fh,1]},
xaxis3={"title": None, "showticklabels": False},
yaxis3={"title": None, "showticklabels": False},
height=fig.layout["height"] + fig_bottom.layout["height"],
)
figall.update_traces(marker_coloraxis=None)
# recenter annotations....
for i, a in enumerate(figall.layout["annotations"]):
a["y"] = (1-i*(fh+.03))-fh/2
figall
Thanks to Rob, according to his answer, I resolved my problem with the following codes:
import pandas as pd
import plotly.express as px
from plotly.subplots import make_subplots
# parameters
files = ["JQ038231.1_RSCU_stack.csv", "MG970255.1_RSCU_stack.csv"]
fig_n = len(files)
space_figs = 0.07
y_offset = 0.8
text_size = 12
width_ = 900
height_ = 700
bottom2fig_ratio = 0.4
row_heights_ = [1/(fig_n+bottom2fig_ratio)]*fig_n + [1/(fig_n+bottom2fig_ratio)*bottom2fig_ratio] # [1/2.5]*2 + [1/2.5*0.5] = [0.4, 0.4, 0.2]
# subplots figure...
figall = make_subplots(rows=fig_n+1, row_heights=row_heights_, vertical_spacing=space_figs, subplot_titles=files)
for num, file in enumerate(files):
row_ = num + 1
rscu = pd.read_csv(file)
rscu = rscu.astype({"Fill": "category"})
rscu = rscu.astype({"aaRatio": "object"})
max_rscu = rscu.groupby(by=["AA"]).sum().max()["RSCU"]
fig = px.bar(rscu, x="AA", y="RSCU", color="Fill", barmode = 'stack', text="aaRatio",
hover_data=['AA', "RSCU"], color_discrete_map={1: "#6598c9", 2: "#cb4a28", 3: "#9ac664", 4: "#7f5499"})
fig.update_traces(textposition='outside') # show text to outside
# set xaxis style
if row_ != fig_n:
fig.update_xaxes(showline=True, linewidth=1, linecolor="black", ticks="outside",
tickangle=0, title=None, showticklabels=False)
else:
fig.update_xaxes(showline=True, linewidth=1, linecolor="black", ticks="outside",
title=None)
# set y range to show annotation text
fig.update_yaxes(showline=True, linewidth=1, linecolor="black", ticks="outside", range=[0, max_rscu + y_offset])
# add all the traces to appropriate subplot
for f in fig.data:
figall.add_trace(f, row=row_, col=1)
# to make fig's layout works in figall
fig.for_each_trace(lambda trace_: trace_.update(xaxis=f"x{row_}", yaxis=f"y{row_}"))
fig.layout[f"xaxis{row_}"] = fig.layout.pop("xaxis")
fig.layout[f"yaxis{row_}"] = fig.layout.pop("yaxis")
fig.layout[f"xaxis{row_}"]["anchor"] = f"y{row_}"
fig.layout[f"yaxis{row_}"]["anchor"] = f"x{row_}"
fig.layout[f"yaxis{row_}"].pop("domain") # otherwise it will affect figall's domain
figall.update_layout(fig.layout)
fig_bottom = px.bar(rscu, x="AA", y="Equality", color="Fill", barmode = 'stack', text="Codon",
hover_data=['AA'], color_discrete_map={1: "#6598c9", 2: "#cb4a28", 3: "#9ac664", 4: "#7f5499"})
fig_bottom.update_traces(textposition='inside') # show text to inside
bottom_row = fig_n+1
fig_bottom.for_each_trace(lambda trace_: trace_.update(xaxis=f"x{bottom_row}", yaxis=f"y{bottom_row}"))
# add all the traces of bottom figure to appropriate subplot
for f in fig_bottom.data:
figall.add_trace(f, row=bottom_row, col=1)
dict_layout = {"barmode": "stack",
"autosize": False,
"showlegend": False,
"plot_bgcolor": "rgba(0, 0, 0, 0)",
"paper_bgcolor": "rgba(0, 0, 0, 0)",
"uniformtext_minsize": text_size,
"uniformtext_mode": "show",
"width": width_,
"height": height_}
# for bottom figure
dict_layout[f"yaxis{fig_n+1}"] = {"title": None, "showticklabels": False}
dict_layout[f"xaxis{fig_n+1}"] = {"title": None, "showticklabels": False}
figall.update_layout(dict_layout)
figall.for_each_annotation(lambda x: x.update(x=0.12, font={"size": 13, "family": "Arial", "color": "black"})) # adjust title of each sub-figure
figall.for_each_trace(lambda trace_: trace_.update(width=0.9)) # set bar width
figall.show()
Hello everyone,
My purpose is to run the below plotly sample code and save the output as HTML file on my hard drive.
Any idea for a go around?
When I run the code I get the following error:
File "C:\Users\rbiberma\AppData\Local\Continuum\anaconda3\lib\site-packages\chart_studio\api\v2\utils.py", line 179, in request
raise exceptions.PlotlyRequestError(message, status_code, content)
PlotlyRequestError: No message
The error is triggered by the code line: py.iplot(fig1, filename='table-right-aligned-plots')
import plotly.plotly as py
import plotly.graph_objs as go
import numpy as np
import pandas as pd
table_trace1 = go.Table(
domain=dict(x=[0, 0.5],
y=[0, 1.0]),
columnwidth = [30] + [33, 35, 33],
columnorder=[0, 1, 2, 3, 4],
header = dict(height = 50,
values = [['<b>Date</b>'],['<b>Number<br>transactions</b>'],
['<b>Output<br>volume(BTC)</b>'], ['<b>Market<br>Price</b>']],
line = dict(color='rgb(50, 50, 50)'),
align = ['left'] * 5,
font = dict(color=['rgb(45, 45, 45)'] * 5, size=14),
fill = dict(color='#d562be')),
cells = dict(values = [df[k].tolist() for k in
['Date', 'Number-transactions', 'Output-volume(BTC)', 'Market-price']],
line = dict(color='#506784'),
align = ['left'] * 5,
font = dict(color=['rgb(40, 40, 40)'] * 5, size=12),
format = [None] + [", .2f"] * 2 + [',.4f'],
prefix = [None] * 2 + ['$', u'\u20BF'],
suffix=[None] * 4,
height = 27,
fill = dict(color=['rgb(235, 193, 238)', 'rgba(228, 222, 249, 0.65)']))
)
trace1=go.Scatter(
x=df['Date'],
y=df['Hash-rate'],
xaxis='x1',
yaxis='y1',
mode='lines',
line=dict(width=2, color='#9748a1'),
name='hash-rate-TH/s'
)
trace2=go.Scatter(
x=df['Date'],
y=df['Mining-revenue-USD'],
xaxis='x2',
yaxis='y2',
mode='lines',
line=dict(width=2, color='#b04553'),
name='mining revenue'
)
trace3=go.Scatter(
x=df['Date'],
y=df['Transaction-fees-BTC'],
xaxis='x3',
yaxis='y3',
mode='lines',
line=dict(width=2, color='#af7bbd'),
name='transact-fee'
)
axis=dict(
showline=True,
zeroline=False,
showgrid=True,
mirror=True,
ticklen=4,
gridcolor='#ffffff',
tickfont=dict(size=10)
)
layout1 = dict(
width=950,
height=800,
autosize=False,
title='Bitcoin mining stats for 180 days',
margin = dict(t=100),
showlegend=False,
xaxis1=dict(axis, **dict(domain=[0.55, 1], anchor='y1', showticklabels=False)),
xaxis2=dict(axis, **dict(domain=[0.55, 1], anchor='y2', showticklabels=False)),
xaxis3=dict(axis, **dict(domain=[0.55, 1], anchor='y3')),
yaxis1=dict(axis, **dict(domain=[0.66, 1.0], anchor='x1', hoverformat='.2f')),
yaxis2=dict(axis, **dict(domain=[0.3 + 0.03, 0.63], anchor='x2', tickprefix='$', hoverformat='.2f')),
yaxis3=dict(axis, **dict(domain=[0.0, 0.3], anchor='x3', tickprefix=u'\u20BF', hoverformat='.2f')),
plot_bgcolor='rgba(228, 222, 249, 0.65)'
)
fig1 = dict(data=[table_trace1, trace1, trace2, trace3], layout=layout1)
plotly.offline.plot(fig1, filename="table-right-aligned-plots")
The desired output:
Answer:
py.iplot(fig1, filename='table-right-aligned-plots')
Should be replaced with: plotly.offline.plot(fig1, filename="table-right-aligned-plots")
I don't think there is currently a way to take what isn't HTML and make it such. Plotly's documentation doesn't list it as an option. You could export the static image in any of a number of ways (you'll note png, webp, jpeg and are built-in, amongst other options). You could also look at kaleido to see if that does what approximately what you need.
But perhaps what you really need is a different graphing library like Plotly's Dash.
I want to create a graph where I want to add range to the secondary y-axis. The graph which I have right now is like this.
The code for this graph is like this:
import plotly.offline as pyo
import plotly.graph_objs as go
from plotly import tools
from plotly.subplots import make_subplots
import pandas as pd
import xlwings as xw
import logging
fileName = 'solar data.xlsx'
app = xw.App(visible=False)
try:
wb = app.books.open(fileName)
sheet = wb.sheets[4]
lastCell = sheet.range('A1').end('down').last_cell.row
solarOne = sheet.range('B2:B'+ str(lastCell)).value
bessOne = sheet.range('D2:D'+ str(lastCell)).value
socOne = sheet.range('E2:E'+ str(lastCell)).value
solarOne_Plus_bessOne = [i+j for i,j in zip(solarOne,bessOne)]
# solarTwo = sheet.range('F2:F' + str(lastCell)).value
# bessTwo = sheet.range('H2:H' + str(lastCell)).value
# socTwo = sheet.range('I2:I' + str(lastCell)).value
# solarTwo_Plus_bessTwo = [i + j for i, j in zip(solarTwo, bessTwo)]
except Exception as e:
logging.exception("Something awful happened!")
print(e)
finally:
app.quit()
app.kill()
fig = go.Figure()
projectTime = pd.date_range("2020-10-01 00:00:00", "2020-10-01 23:59:00", freq="1T")
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Scatter(x = projectTime, y = solarOne, name = 'Solar', fill='tozeroy', line=dict(width=0.5, color='rgb(255,167,0)')), secondary_y=False)
fig.add_trace(go.Scatter(x = projectTime, y = bessOne, name = 'Storage', fill='tozeroy', line=dict(width=0.5, color='rgb(43, 201, 34)')), secondary_y=False)
fig.add_trace(go.Scatter(x = projectTime, y = socOne, name = 'SoC', fill='tozeroy', line=dict(width=0.5, color='rgb(250, 67, 67)')), secondary_y=True)
fig.add_trace(go.Scatter(x = projectTime, y = solarOne_Plus_bessOne, name = 'Solar + BESS', fill='tozeroy',), secondary_y=False)
# Add figure title
fig.update_layout(
title_text="Solar with 0.5MW 0.5Hour storage"
)
# Set x-axis title
fig.update_xaxes(title_text="Time")
# Set y-axes titles
fig.update_yaxes(title_text="Dispatch(MW) and SoC(MWh)")
pyo.plot(fig, filename='Solar with 0.5MW 0.5Hour storage example 1.html')
I have tried to add layout_yaxis_range=[-0.6, 0.7] in secondary y-axis but it throws an error
TypeError: add_trace() got an unexpected keyword argument 'layout_yaxis_range'
I want this secondary y-axis with the same x-axis. Can anyone please help?
This works for me in similar cases:
fig.update_yaxes(range=[-0.6, 0.7], secondary_y=True)
I have written the following code to heat heatmap of US-States. But I am unable to get the output image in Google Colab.
State codes are two alphabet codes for a particular state of the US.
temp = pd.DataFrame(project_data.groupby("school_state")["project_is_approved"].apply(np.mean)).reset_index()
temp.columns = ['state_code', 'num_proposals']
scl = [[0.0, 'rgb(242,240,247)'],[0.2, 'rgb(218,218,235)'],[0.4, 'rgb(188,189,220)'],\
[0.6, 'rgb(158,154,200)'],[0.8, 'rgb(117,107,177)'],[1.0, 'rgb(84,39,143)']]
data = [ dict(
type='choropleth',
colorscale = scl,
autocolorscale = False,
locations = temp['state_code'],
z = temp['num_proposals'].astype(float),
locationmode = 'USA-states',
text = temp['state_code'],
marker = dict(line = dict (color = 'rgb(255,255,255)',width = 2)),
colorbar = dict(title = "% of pro")
) ]
layout = dict(
title = 'Project Proposals % of Acceptance Rate by US States',
geo = dict(
scope='usa',
projection=dict( type='albers usa' ),
showlakes = True,
lakecolor = 'rgb(255, 255, 255)',
),
)
fig = dict(data=data, layout=layout)
offline.iplot(fig, filename='us-map-heat-map')
I have imported following libraries:
from chart_studio import plotly
import plotly.offline as offline
import plotly.graph_objs as go
offline.init_notebook_mode()
from collections import Counter
import chart_studio.plotly as py
Try the following code with your data:
(I tried putting your variables in the correct spots)
choropleth = go.Choropleth(
locations=temp['state_code'],
locationmode='USA-states',
z = temp['num_proposals'].astype(float),
zmin = 0,
zmax = max(temp['num_proposals'].astype(float)),
colorscale=scl,
autocolorscale=False,
text='Proposals',
marker_line_color='white',
colorbar_title="% Acceptance Rate"
)
fig = go.Figure(data=choropleth)
fig.update_layout(
title_text='Project Proposals % of Acceptance Rate by US States',
geo = dict(
scope='usa',
projection=go.layout.geo.Projection(type = 'albers usa'),
showlakes=True,
lakecolor='rgb(255, 255, 255)'),
)
fig.show()
This code works by creating the Plotly Choropleth Graph Object with your data, then loading that object into a Plotly Figure Graph Object, then updating the layout (for proper titles and zooms), and finally displaying the figure.