4

Using Plotly for a bar plot preserves the dataset's order when not using color:

import pandas as pd
import plotly.express as px

df = pd.DataFrame({'val': [1, 2, 3],
                   'type': ['b', 'a', 'b']},
                  index=['obs1', 'obs2', 'obs3'])
px.bar(df, 'val')

enter image description here But color reorders the data:

px.bar(df, 'val', color='type')

enter image description here

How can I preserve the original ordering while using the color arg?

This is similar to How can I retain desired order in R Plotly bar chart with color variable, but I'm using Python rather than R.

Max Ghenis
  • 14,783
  • 16
  • 84
  • 132

3 Answers3

7

You could use the category_orders parameter:

import pandas as pd
import plotly.express as px

df = pd.DataFrame({'val': [1, 2, 3],
                   'type': ['b', 'a', 'b']},
                  index=['obs1', 'obs2', 'obs3'])
fig = px.bar(df, 'val', color='type', category_orders={'index': df.index[::-1]})
fig.show()

Output

enter image description here

From the documentation:

This parameter is used to force a specific ordering of values per column. The keys of this dict should correspond to column names, and the values should be lists of strings corresponding to the specific display order desired.

By looking at the code it seems that color is being used as a grouping attribute, so that's probably why the reordering is happening.

Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
4

I don't really know why plotly express do it, but you can use a workaround as using an array to reorder the yaxis fig.update_layout( yaxis={'categoryorder':'array', 'categoryarray':df.index}):

import pandas as pd
import plotly.express as px

df = pd.DataFrame({'val': [1, 2, 3],
                   'type': ['b', 'a', 'b']},
                  index=['obs1', 'obs2', 'obs3'])
fig=px.bar(df, x='val',y=df.index, orientation='h')


fig=px.bar(df, x='val',y=df.index, color='type', orientation='h')
fig.update_layout( yaxis={'categoryorder':'array', 'categoryarray':df.index})

result:

enter image description here

Renaud
  • 2,709
  • 2
  • 9
  • 24
0

Plotly express seems to group the data according to color when color='type' is used. The following worked for me and kept bars' order:

import pandas as pd
import plotly.express as px

df = pd.DataFrame({'val': [1, 2, 3],
               'type': ['b', 'a', 'b']},
              index=['obs1', 'obs2', 'obs3'])

fig=px.bar(df, x='val',y=df.index)
fig.update_traces(marker_color=['#ebb36a' if i=='a' else '#6dbf9c' for i in df.type]
, showlegend=False)