'plotly: add box plot as subplot
I'm attempting to create a visualization where a pie chart appears on top, and a box plot appears below. I'm using the plotly library.
I tried using this code:
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
fig = make_subplots(
rows=2, cols=1,
specs=[[{'type':'pie'}], [{'type':'box'}]],
)
# pie chart
pie = go.Pie(values=[1, 2, 3, 4, 5], labels=['a', 'b', 'a', 'a', 'c'], sort=False)
# box plot
import numpy as np
np.random.seed(1)
y0 = [10, 1, 2, 3, 1, 5, 8, 2]
y1 = [10, 1, 2, 3, 1, 5, 8, 2]
box = go.Figure()
box.add_trace(go.Box(y=y0))
box.add_trace(go.Box(y=y1))
# add pie chart and box plot to figure
fig.add_trace(pie, row=1, col=1)
fig.add_trace(box, row=2, col=1)
fig.update_traces(textposition='inside', textinfo='percent+label')
fig.show()
However, I'm encountering this error:
Invalid element(s) received for the 'data' property of
Invalid elements include: [Figure({
'data': [{'type': 'box', 'y': [10, 1, 2, 3, 1, 5, 8, 2]}, {'type': 'box', 'y': [10, 1, 2, 3, 1, 5, 8, 2]}],
'layout': {'template': '...'}
})]
Solution 1:[1]
There are two errors in your code
boxis created as a figure.add_trace()adds a trace not a figure. Changed to loop through traces inboxfigureupdate_traces()is updating attributes that don't exist in a Box trace. Changed to usefor_each_trace()and update attribute that are valid for trace type
full code
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
fig = make_subplots(
rows=2,
cols=1,
specs=[[{"type": "pie"}], [{"type": "box"}]],
)
# pie chart
pie = go.Pie(values=[1, 2, 3, 4, 5], labels=["a", "b", "a", "a", "c"], sort=False)
# box plot
import numpy as np
np.random.seed(1)
y0 = [10, 1, 2, 3, 1, 5, 8, 2]
y1 = [10, 1, 2, 3, 1, 5, 8, 2]
box = go.Figure()
box.add_trace(go.Box(y=y0))
box.add_trace(go.Box(y=y1))
# add pie chart and box plot to figure
fig.add_trace(pie, row=1, col=1)
# fig.add_trace(box, row=2, col=1)
for t in box.data:
fig.add_trace(t, row=2, col=1)
# fig.update_traces(textposition='inside', textinfo='percent+label')
fig.for_each_trace(
lambda t: t.update(textposition="inside", textinfo="percent+label")
if isinstance(t, go.Pie)
else t
)
fig.show()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Rob Raymond |

