0

Here is my code for the dataframe

df = pd.DataFrame({'var_1':['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'], 
                   'var_2':['m', 'n', 'o', 'm', 'n', 'o', 'm', 'n', 'o'], 
                   'var_3':[np.random.randint(25, 33) for _ in range(9)]})

Here is the dataframe that I have

var_1   var_2   var_3
0   a   m   27
1   a   n   28
2   a   o   28
3   b   m   31
4   b   n   30
5   b   o   25
6   c   m   27
7   c   n   32
8   c   o   27

Here is the code I used to get the stacked bar plot

fig = px.bar(df, x='var_3', y='var_1', color='var_2', orientation='h', text='var_3')
fig.update_traces(textposition='inside', insidetextanchor='middle')
fig

enter image description here

But I want the bar to stack in descending order of the values, largest at the start/bottom and smallest at top
How should I update the layout to get that

2
  • To clarify, you want largest var_3 at bottom? (and you intend for the colours to demark separate entities too?) So bottom would be largest of m + n + 0 for any particular var_1? Commented Apr 19, 2021 at 16:27
  • I don't want m-n-o in order. Which ever is the largest, it should be at the begining If m is the largest, then it should be at the start, then the second-largest, and then the third in the stacking order Commented Apr 19, 2021 at 16:34

1 Answer 1

1
df = pd.DataFrame({'var_1':['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'], 
                   'var_2':['m', 'n', 'o', 'm', 'n', 'o', 'm', 'n', 'o'], 
                   'var_3':[np.random.randint(25, 33) for _ in range(9)]})

df.sort_values(['var_1', 'var_3'], ignore_index=True, inplace=True, ascending=False)

# colors
colors = {'o': 'red',
          'm': 'blue',
          'n': 'green'}

# traces
data = []

# loop across the different rows
for i in range(df.shape[0]):
        data.append(go.Bar(x=[df['var_3'][i]],
                           y=[df['var_1'][i]],
                           orientation='h',
                           text=str(df['var_3'][i]),
                           marker=dict(color=colors[df['var_2'][i]]),
                           name=df['var_2'][i],
                           legendgroup=df['var_2'][i],
                           showlegend=(i in [1, 2, 3])))
        
# layout
layout = dict(barmode='stack', 
              yaxis={'title': 'var_1'},
              xaxis={'title': 'var_3'})

# figure
fig = go.Figure(data=data, layout=layout)    
fig.update_traces(textposition='inside', insidetextanchor='middle')
fig.show()

StackBar

Sign up to request clarification or add additional context in comments.

1 Comment

Yep - I was thinking the data would have to be flattened, haven't found a built in workaround yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.