получить тот же порядок данных в строке стека python plotly

#python #pandas #dataframe #bar-chart #plotly-python

#python #pandas #фрейм данных #гистограмма #plotly-python

Вопрос:

создал гистограмму стека, чтобы визуализировать распределение времени для каждого дня работы машины. Но не могу получить тот же порядок данных в строке стека.

Пример: День 01-09, исходный порядок данных выполняется (36068 сек.) и состояние B (6842 сек.), Но в стековой строке первым является состояние B, а затем состояние выполнения. Таким образом, мы можем получить тот же порядок данных в строке стека?

введите описание изображения здесь

код с фреймом данных:

 import pandas as pd
import plotly.express as px

df = pd.DataFrame({'Day-Shift': {0: 'Day 01-05',
  1: 'Day 01-05',
  2: 'Day 01-05',
  3: 'Day 01-05',
  4: 'Night 01-05',
  5: 'Day 01-06',
  6: 'Day 01-06',
  7: 'Day 01-06',
  8: 'Day 01-06',
  9: 'Day 01-06',
  10: 'Day 01-06',
  11: 'Night 01-06',
  12: 'Day 01-07',
  13: 'Night 01-07',
  14: 'Night 01-07',
  15: 'Night 01-07',
  16: 'Night 01-07',
  17: 'Night 01-07',
  18: 'Night 01-08',
  19: 'Night 01-08',
  20: 'Night 01-08',
  21: 'Night 01-08',
  22: 'Day 01-08',
  23: 'Day 01-08',
  24: 'Day 01-08',
  25: 'Night 01-09',
  26: 'Night 01-09',
  27: 'Night 01-09',
  28: 'Day 01-09',
  29: 'Day 01-09',
  30: 'Day 01-09',
  31: 'Day 01-09',
  32: 'Day 01-10',
  33: 'Night 01-10',
  34: 'Day 01-11',
  35: 'Day 01-11',
  36: 'Day 01-11',
  37: 'Day 01-11',
  38: 'Day 01-11',
  39: 'Night 01-11',
  40: 'Day 01-12',
  41: 'Night 01-12',
  42: 'Day 01-13',
  43: 'Day 01-13',
  44: 'Day 01-13',
  45: 'Day 01-13',
  46: 'Day 01-13',
  47: 'Day 01-13',
  48: 'Day 01-13',
  49: 'Night 01-13',
  50: 'Day 01-14',
  51: 'Day 01-14',
  52: 'Day 01-14',
  53: 'Day 01-14',
  54: 'Day 01-14',
  55: 'Day 01-14',
  56: 'Day 01-14',
  57: 'Day 01-14',
  58: 'Day 01-14',
  59: 'Night 01-14'},
 'State': {0: 'D',
  1: 'STOPPED',
  2: 'B',
  3: 'A',
  4: 'A',
  5: 'A',
  6: 'A1',
  7: 'A2',
  8: 'A3',
  9: 'A4',
  10: 'B1',
  11: 'B1',
  12: 'B1',
  13: 'B1',
  14: 'B2',
  15: 'STOPPED',
  16: 'RUNNING',
  17: 'B',
  18: 'STOPPED',
  19: 'B',
  20: 'RUNNING',
  21: 'D',
  22: 'STOPPED',
  23: 'B',
  24: 'RUNNING',
  25: 'STOPPED',
  26: 'RUNNING',
  27: 'B',
  28: 'RUNNING',
  29: 'STOPPED',
  30: 'B',
  31: 'D',
  32: 'B',
  33: 'B',
  34: 'B',
  35: 'RUNNING',
  36: 'STOPPED',
  37: 'D',
  38: 'A',
  39: 'A',
  40: 'A',
  41: 'A',
  42: 'A',
  43: 'A1',
  44: 'A2',
  45: 'A3',
  46: 'A4',
  47: 'B1',
  48: 'B2',
  49: 'B2',
  50: 'B2',
  51: 'B',
  52: 'STOPPED',
  53: 'A',
  54: 'A1',
  55: 'A2',
  56: 'A3',
  57: 'A4',
  58: 'B1',
  59: 'B1'},
 'seconds': {0: 7439,
  1: 0,
  2: 10,
  3: 35751,
  4: 43200,
  5: 7198,
  6: 18,
  7: 14,
  8: 29301,
  9: 6,
  10: 6663,
  11: 43200,
  12: 43200,
  13: 5339,
  14: 8217,
  15: 0,
  16: 4147,
  17: 1040,
  18: 24787,
  19: 1500,
  20: 14966,
  21: 1410,
  22: 2499,
  23: 1310,
  24: 39391,
  25: 3570,
  26: 17234,
  27: 47390,
  28: 36068,
  29: 270,
  30: 6842,
  31: 20,
  32: 43200,
  33: 43200,
  34: 2486,
  35: 8420,
  36: 870,
  37: 30,
  38: 31394,
  39: 43200,
  40: 43200,
  41: 43200,
  42: 36733,
  43: 23,
  44: 6,
  45: 4,
  46: 4,
  47: 3,
  48: 6427,
  49: 43200,
  50: 620,
  51: 0,
  52: 4,
  53: 41336,
  54: 4,
  55: 4,
  56: 4,
  57: 23,
  58: 1205,
  59: 43200}})

dfs = df['Day-Shift'].str.extract('([a-zA-Z] )([^a-zA-Z] )', expand=True)
dfs.columns = ['tod', 'date']
dfs['date2'] = dfs['date']   '-2021'
dfs['date2'] = pd.to_datetime(dfs['date2'])

df = pd.concat([df, dfs], axis = 1)
df = df.sort_values(['date2', 'tod'], ascending = [True, True])

new_order = list(df['Day-Shift'].unique())
# df['Day-Shift'] = pd.Categorical(df['Day-Shift'], categories=new_order, ordered=True)

fig = px.bar(df, x="Day-Shift", y="seconds", color="State",
            category_orders = {'Day-Shift': new_order})
fig.update_xaxes(type='category')
fig.show()
 

Ответ №1:

Plotly заботится о порядке добавления данных.

Таким образом, чтобы изменить каждый столбец, вы должны изменить порядок, в котором plotly получает данные для каждого столбца.

Для вас это означает, что для каждого дня / ночи вам нужно будет менять значения, как у меня ниже.

Вот код:

 import json

## Get the values of each data dict as lists
shifts  = list(data['Shifts'].values())
seconds = list(data['Seconds'].values())
states  = list(data['States'].values())

shifts_indexed = []
shift_indexed  = []

## Put each shift's indexes into a separate list
## Then those lists into a list of index lists
for index in range(len(shifts)):

    shift = shifts[index]

    ## Can't get previous index yet because there isn't one
    if index == 0:

        shift_indexed.append(index)

    ## If index is the last one
    elif index == (len(shifts)-1):

        shift_indexed.append(index)
        shifts_indexed.append(shift_indexed)

    ## Compare all other shifts to the last shift to see if it's a new shift
    ## If it's a new shift, add the shift's index to the list of shifts
    ## Then reset the shift_indexed list for the next shift
    else:

        last_index = index - 1
        last_shift = shifts[last_index]

        ## Shift is different
        if shift != last_shift:

            ## Add the shifts index list to list of shifts
            shifts_indexed.append(shift_indexed)

            ## Clear the list for the next shift
            shift_indexed = []

            ## Add the new shift to the newly cleared index list
            shift_indexed.append(index)

        ## Shift is the same
        else:

            shift_indexed.append(index)

## Remake dictionary

fixed        = {}

fixed_shifts = {}
fixed_secs   = {}
fixed_states = {}

## For each list of shift indexes
for list in shifts_indexed:

    # Get the list of shift indexes but in reverse
    r_list = list[:None:-1]

    ## Create dictionaries using the indexes in the reversed index list (r_list)
    for i in range(len(list)):

        index   = list[i]
        r_index = r_list[i]

        shift   = shifts[index]
        second  = seconds[index]
        state   = states[index]

        fixed_shifts[r_index] = shift
        fixed_secs[r_index]   = second
        fixed_states[r_index] = state

## Set to final dictionary
fixed['Shifts']  = fixed_shifts
fixed['Seconds'] = fixed_secs
fixed['States']  = fixed_states

print('nDatann' json.dumps(data, sort_keys=True, indent=4))
print('nFixednn' json.dumps(fixed, sort_keys=True, indent=4))
 

Перед:

 data = {

        'Shifts': {
            0: 'Day 01-05',
            1: 'Day 01-05',
            2: 'Day 01-05',
            3: 'Day 01-05'
        },

        'States':     {
            0: 'D',
            1: 'STOPPED',
            2: 'B',
            3: 'A'
        },

        'Seconds':   {
            0: 7439,
            1: 0,
            2: 10,
            3: 35751
        }
    
}
 

После:

 data = {

        'Shifts': {
            0: 'Day 01-05',
            1: 'Day 01-05',
            2: 'Day 01-05',
            3: 'Day 01-05'
        },

        'States':     {
            0: 'A',
            1: 'B',
            2: 'STOPPED',
            3: 'D'
        },

        'Seconds':   {

            0: 35751,
            1: 10,
            2: 0,
            3: 7439
        }

}
 

Комментарии:

1. не могли бы вы уточнить свой ответ с помощью кода?

2. @domahc Я обновил свой ответ рабочим кодом