Here some code to demonstrate what I already tried.
This works, but with facets instead of groups:
import pandas as pd
import numpy as np
import plotly.express as px
df = pd.DataFrame(index=pd.MultiIndex.from_product([
pd.date_range(start="2022-01", end="2022-12", freq="MS"),
["A", "B", "C", "D", "E", "F"],
["a", "b", "c"],
["plan", "actual"],
], names=["dim1", "dim2", "dim3", "dim4"])).reset_index()
df["value"]=np.random.random(len(df))
barsp = []
fig = px.bar(data_frame=df,
x=df.dim1,
y=df.value,
color=df.dim2,
pattern_shape=df.dim3,
facet_row=df.dim4,
)
fig.show()
This does produces errors:
import pandas as pd
import numpy as np
import plotly.express as px
df = pd.DataFrame(index=pd.MultiIndex.from_product([
pd.date_range(start="2022-01", end="2022-12", freq="MS"),
["A", "B", "C", "D", "E", "F"],
["a", "b", "c"],
["plan", "actual"],
], names=["dim1", "dim2", "dim3", "dim4"])).reset_index()
df["value"]=np.random.random(len(df))
fig = px.bar(data_frame=df, x=np.stack([df.loc[df.dim4==v, "dim1"] for v in df["dim4"].unique()]),
y=np.stack([df.loc[df.dim4==v, "value"] for v in df["dim4"].unique()]),#.flatten(),
# color=np.stack([df.loc[df.dim4==v, "dim2"] for v in df["dim4"].unique()]),#.flatten(),
# pattern_shape=np.stack([df.loc[df.dim4==v, "dim3"] for v in df["dim4"].unique()]),#.flatten(),
)
fig.show()
ValueError : Cannot accept list of column references or list of columns for both x
and y
.
If I flatten y then
ValueError : All arguments should have the same length. The length of argument wide_variable_0
is 216, whereas the length of previously-processed arguments [โyโ] is 432
The following code tries to patch and assemble traces created with px:
import pandas as pd
import numpy as np
import plotly.express as px
df = pd.DataFrame(index=pd.MultiIndex.from_product([
pd.date_range(start="2022-01", end="2022-12", freq="MS"),
["A", "B", "C", "D", "E", "F"],
["a", "b", "c"],
["plan", "actual"],
], names=["dim1", "dim2", "dim3", "dim4"])).reset_index()
df["value"]=np.random.random(len(df))
barsp = []
for gi, gv in enumerate(df.dim4.unique()):
barsp.append(dict(data_frame=df[df.dim4==gv], x="dim1",
y="value",
color="dim2",
pattern_shape="dim3",
))
fig = px.bar(**barsp[0])
fig.update_traces(xaxis="x1")
# print(fig["layout"])#.select_traces()))
step = 1./len(barsp)
for i, bp in enumerate(barsp[1:]):
b = px.bar(**bp)
fig.update_traces(xaxis=f"x{i+2}")
for t in b.select_traces():
fig.add_trace(t)
# for i in range(len(barsp)):
# fig.update_layout(**{f"xaxis{i+1}":dict(***Is there something to patch here? anchor? ***)})
fig.show()
All traces are included in the legend. But the bars of one dim4 group is visible. They groups of dim4 are not even drawn over each other. Maybe the whole plotting area covers the other groups.
How can I make them all visible and give each group an x-offset?