简体   繁体   中英

How to sort x-axis label and legends in python plotly express?

Sorting X-axis labels

I have a python dict containing list of dicts which I am flattening and sorting using pandas dataframe in wide-form. What I expect to see in the plotly figure is that the x axis labels to be grouped and sorted with respect to year and period. The period here could take range between 1-52. But what I am seeing is that one of the groups is not sorted (or not fully sorted). I tried updating categoryorder doc . It doesn't seem to work as I expected. This is the order in which I expect to see for one of the group on the x-axis labels:

T311-PM2:2019-8, T311-PM2:2019-11, T311-PM2:2019-12, T311-PM2:2020-3.

Sorting legends

A similar behavior with the legends as well. I tried sorting using legend_traceorder doc .

I expect to see this order instead:

CS1 P, CS1-1 P, CS2 P, CS3 P, CS4 C, CS5 R, CS6 P, CS7-1 C, CS7-2 S, CS8 P

This is the dict data I will be using in my code:

response_dict = {
    "data": [
        {
            "machineType": "L10-Alpha1-PM4",
            "date": "2021-1",
            "event": "CS3 P",
            "mins": "0.00"
        },
        {
            "machineType": "L10-Alpha1-PM4",
            "date": "2021-1",
            "event": "CS7-2 S",
            "mins": "7.14"
        },
        {
            "machineType": "L10-Alpha1-PM4",
            "date": "2021-1",
            "event": "CS8 P",
            "mins": "4.17"
        },
        {
            "machineType": "T311-PM2",
            "date": "2019-8",
            "event": "CS1 P",
            "mins": "21.14"
        },
        {
            "machineType": "T311-PM2",
            "date": "2019-11",
            "event": "CS4 C",
            "mins": "2.92"
        },
        {
            "machineType": "T311-PM2",
            "date": "2019-11",
            "event": "CS5 R",
            "mins": "327.88"
        },
        {
            "machineType": "T311-PM2",
            "date": "2019-12",
            "event": "CS7-1 C",
            "mins": "43.90"
        },
        {
            "machineType": "T311-PM2",
            "date": "2019-12",
            "event": "CS6 P",
            "mins": "2147.27"
        },
        {
            "machineType": "T311-PM2",
            "date": "2019-8",
            "event": "CS8 P",
            "mins": "0.10"
        },
        {
            "machineType": "T311-PM2",
            "date": "2020-3",
            "event": "CS8 P",
            "mins": "19.31"
        },
        {
            "machineType": "T828-PM2",
            "date": "2018-5",
            "event": "CS1-1 P",
            "mins": "11.43"
        },
        {
            "machineType": "T828-PM2",
            "date": "2018-5",
            "event": "CS2 P",
            "mins": "10.83"
        }
    ]
}

My Code

import pandas as pd
import plotly.express as px

df_normalized = pd.json_normalize(response_dict['data'])
df_normalized['Mission'] = df_normalized[['machineType', 'date']].agg(':'.join, axis=1)
df_normalized[['year', 'period']] = df_normalized['date'].str.split('-', expand=True).astype(int)
data_frame = df_normalized.sort_values(by=['year', 'period'])
figure = px.bar(data_frame, x='Mission', y='date', color='event').update_xaxes(categoryorder='category ascending')#.update_layout(legend_traceorder='normal')
figure.show()

Plot

在此处输入图像描述

You were headed in the right direction, just need use category_orders instead of categoryorder , and define the order of data using sorted() method.

df_normalized = pd.json_normalize(response_dict['data'])
df_normalized['Mission'] = df_normalized[['machineType', 'date']].agg(':'.join, axis=1)
df_normalized[['year', 'period']] = df_normalized['date'].str.split('-', expand=True).astype(int)
data_frame = df_normalized.sort_values(by=['year', 'period']).reset_index(drop=True)
figure = px.bar(data_frame, x='Mission',y='date', color='event',\
                category_orders={'event':sorted(data_frame.event.unique()),\
                                 'Mission':sorted(data_frame.Mission,\
                                                  key = lambda x: pd.to_datetime(x.split(':')[1]))})
figure.show()

PS: I generally use .reset_index(drop=True) after .sort_values() on a DataFrame, to maintain correct order of index values.

像素栏

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM