Open
Description
Plotly 5.15.0
Python 3.11
When creating a stacked bar chart with a sorted dataframe the order of bars is inconsistent. In some cases I get the desired result sorted by total bar length and in other cases I get what appears to be sorted by category.
For example, the following sorted dataframe is charted with the expected bar order:
index name category value total
0 2 rnlblpykns cat1 75 173
1 4 rnlblpykns cat3 66 173
2 1 rnlblpykns cat0 26 173
3 3 rnlblpykns cat2 6 173
4 8 lfqlfxlpxt cat1 77 86
5 7 lfqlfxlpxt cat0 9 86
6 5 axnqvjlmql cat0 46 54
7 6 axnqvjlmql cat1 8 54
8 0 zfbcsrusbq cat0 18 18
While the chart for the following sorted dataframe appears to be ordered by 'name':
index name category value total
0 4 tprmmexxdf cat4 96 307
1 1 tprmmexxdf cat1 89 307
2 0 tprmmexxdf cat0 58 307
3 2 tprmmexxdf cat2 54 307
4 3 tprmmexxdf cat3 10 307
5 10 iontrwxbjg cat0 91 271
6 11 iontrwxbjg cat1 86 271
7 13 iontrwxbjg cat3 46 271
8 14 iontrwxbjg cat4 37 271
9 12 iontrwxbjg cat2 11 271
10 7 ffxalebxgi cat2 57 234
11 8 ffxalebxgi cat3 48 234
12 5 ffxalebxgi cat0 44 234
13 9 ffxalebxgi cat4 44 234
14 6 ffxalebxgi cat1 41 234
15 16 bzbaayrcra cat1 78 146
16 15 bzbaayrcra cat0 55 146
17 18 bzbaayrcra cat3 8 146
18 17 bzbaayrcra cat2 5 146
19 20 ejehjurxge cat1 50 132
20 22 ejehjurxge cat3 39 132
21 23 ejehjurxge cat4 22 132
22 21 ejehjurxge cat2 15 132
23 19 ejehjurxge cat0 6 132
The code is as follows:
import random
import string
import plotly.express as px
import pandas as pd
def random_dataframe():
names = []
categories = []
values = []
for i in range(random.randint(3, 6)):
letters = string.ascii_lowercase
name = ''.join(random.choice(letters) for i in range(10))
for j in range(random.randint(1, 5)):
names.append(name)
categories.append(f"cat{j}")
values.append(random.randint(1, 100))
df = pd.DataFrame({
"name": names,
"category": categories,
"value": values
})
return df
df = random_dataframe()
df["total"] = df.groupby("name")["value"].transform(sum)
df = df.sort_values(by=["total", "name", "value"], ascending=False).reset_index()
print(df)
fig = px.bar(
df,
x="value",
y="name",
orientation="h",
color="category",
width=640,
height=480
)
fig.show()