Reputation: 60
I'm trying to create a simple pdf of a subplot consisting of one bar chart and one data table:
The Bar and table function works but when i try and create a subplot plotly gives the following error:
ValueError:
Invalid element(s) received for the 'data' property of
Invalid elements include
I wrote the following: Does it not like that i looped the bar traces?
I first create functions to build the bar chart and data table:
import plotly
import plotly.graph_objects as go
import plotly.figure_factory as ff
import os
import numpy as np
from plotly.subplots import make_subplots
import pandas as pd
def build_barchart(df,columns):
x = df.City.unique() # City column should always be the x axis
fig = go.Figure()
fig.update_layout(barmode='stack')
for column in columns:
Y=df[column].tolist()
fig.add_trace(go.Bar(name=column,x=x,y=Y))
return fig
def build_table(df):
table = ff.create_table(df)
return table
def create_pdf(df,columns):
fig = make_subplots(rows=1, cols=2)
fig.add_trace(
build_barchart(df,columns),
row=1, col=1
)
fig.add_trace(
build_table(df),
row=1, col=2
)
if not os.path.exists("images"):
os.mkdir("images")
fig.write_image("images/fig1.pdf")
return
After creating the build functions i try and use them...
df = pd.read_csv('DATA.csv', delimiter=';')
columns=['%Something','%Dogs','%Cats','%Cars']
table = build_table(df)
bars = build_barchart(df,columns)
fig = make_subplots(rows=1, cols=2)
fig.add_trace(
bars,
row=1, col=1
)
fig.add_trace(
table,
row=1, col=2
)
fig.show()
test data
City;%Something;%Dogs;%Cats;%Cars;Nr Alarms;Nr Block
USA;60;10;5;25;1;1
CANADA;20;10;5;65;2;2
MEXICO;90;5;5;0;3;3
SWEDEN;10;10;5;75;4;4
Upvotes: 1
Views: 237
Reputation: 13437
Please don't take it as an answer. Given that your code has some pitfalls I'm adding a polished version. In particular in case you have duplicated countries x = df.City.astype('str').unique()
is not going to work well with Y
and you should arrange/check your data before to plot.
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
df = pd.DataFrame({
'City': {0: 'USA', 1: 'CANADA', 2: 'MEXICO', 3: 'SWEDEN'},
'%Something': {0: 60, 1: 20, 2: 90, 3: 10},
'%Dogs': {0: 10, 1: 10, 2: 5, 3: 10},
'%Cats': {0: 5, 1: 5, 2: 5, 3: 5},
'%Cars': {0: 25, 1: 65, 2: 0, 3: 75},
'Nr Alarms': {0: 1, 1: 2, 2: 3, 3: 4},
'Nr Block': {0: 1, 1: 2, 2: 3, 3: 4}})
def build_subplot(df, columns=None):
if columns is None:
columns = df.columns
# only columns starting with %
columns = [col for col in columns if col.startswith("%")]
fig = make_subplots(rows=1, cols=2,
specs=[
[{"type": "bar"},{"type": "table"}]
]
)
fig.update_layout(barmode='stack')
for column in columns:
fig.append_trace(
go.Bar(x=df["City"],
y=df[column],
name=column),
row=1,col=1)
fig.add_trace(
go.Table(
header=dict(
values=df.columns,
font=dict(size=10),
align="left"
),
cells=dict(
values=df.T.values.tolist(),
align = "left")
),
row=1, col=2
)
return fig
build_subplot(df, ['%Something', '%Dogs', 'Nr Block'])
Addendum: I think it will look better if you can have your subplot with 1 column and 2 rows as some details from the table could be hard to read.
Upvotes: 1
Reputation: 60
Figured out what i did wrong!
Instead of using plotly.figure_factory's create_table() i used plotly.graph_objects Table()
I also had to define the type of figure used in the creation of the subplot. The final solution for creating the subplot looks like this:
def build_subplot(df,columns):
x = df.City.astype('str').unique()
fig = make_subplots(rows=1, cols=2,
specs=[
[{"type": "bar"},{"type": "table"}]
]
)
fig.update_layout(barmode='stack')
for column in columns:
Y=df[column].tolist()
fig.append_trace(go.Bar(name=column,x=x,y=Y),row=1,col=1)
fig.add_trace(
go.Table(
header=dict(
values=df.columns,
font=dict(size=10),
align="left"
),
cells=dict(
values=[df[k].tolist() for k in df.columns],
align = "left")
),
row=1, col=2
)
return fig
I hope this helps someone else :)
Upvotes: 0