【问题标题】:get the same data order in stack bar python plotly在堆栈栏中python plotly获取相同的数据顺序
【发布时间】:2021-02-15 05:35:39
【问题描述】:

创建了一个堆叠条形图来可视化机器每一天的时间分布。但无法在堆栈栏中获取相同的数据顺序。

例如:Day 01-09,原始数据顺序是 Running(36068 sec.) 和 state B(6842 sec.),但在堆积条形图中,第一个是 State B,然后是 Running 状态。这样我们可以在stack bar中得到相同的数据顺序吗?

带有数据框的代码:

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()

【问题讨论】:

    标签: python pandas dataframe bar-chart plotly-python


    【解决方案1】:

    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('\nData\n\n'+json.dumps(data, sort_keys=True, indent=4))
    print('\nFixed\n\n'+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
            }
    
    }
    

    【讨论】:

    • 你能用代码详细说明你的答案吗?
    • @domahc 我已经用工作代码更新了我的答案
    猜你喜欢
    • 2021-07-13
    • 2011-03-03
    • 2020-04-01
    • 2021-10-23
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 2011-01-12
    • 2021-08-07
    相关资源
    最近更新 更多