1

hi I have a df with 3 columns: "Day-Shift", "State", "seconds".

Need to visualize this data using stack bar chart but keeping data as it is.

 Day-Shift   State          seconds
    Day 01-05   A              7439
    Day 01-05   STOPPED        0
    Day 01-05   B              10
    Day 01-05   C              35751
    Night 01-05 C              43200
    Day 01-06   STOPPED        7198
    Day 01-06   F              18
    Day 01-06   A              14
    Day 01-06   A              29301
    Day 01-06   STOPPED        6
    Day 01-06   A              6663
    Night 01-06 A              43200

Chart X-axis: "Day-shift",Y:"seconds",color:"State"" I created stack bar using python plotly but data order is not the same as in dataframe. enter image description here

Ex: in Night 01-08 need to plot this same as in this df's order(Stoped -> B -> Running -> D). But graph shows D-> Stopped ->B -> Running . Is there any way to create stack bar keeping the same dataframe order as it is using matplotlib? i didnt use matplotlib before.

DF:

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}})
2
  • Please research on a matplotlib implementation, then make an earnest attempt at solution. Update post with a specific question related to attempt. Commented Feb 16, 2021 at 22:57
  • hi @Parfait i researched a lot about matplotlib stack bar. But my requirement is a little bit hard. i saw a lot of articles about matplotlib stack bar carts. But didn't see a single article about stack bar with keeping the data order is same as dataframe order. Commented Feb 17, 2021 at 5:00

1 Answer 1

1

You can plot the bar corresponding to each shift independently as a stacked bar, so preserving the order in the original dataframe. Here the code:

# Get all the possible states and associate a color to each of them
all_states = df.State.unique()
cm = plt.get_cmap('tab20')  # you can choose the colormap you want
colors = {
    s: cm(1. * i / len(all_states))  # get a different color for each state, sampling the color map
    for i, s in enumerate(all_states)
}

fig, ax = plt.subplots(1, 1)
day_shifts = df['Day-Shift'].unique()
# Plot the bar of each shift independently, so preserving the order of the stack
for i, d in enumerate(day_shifts):
    total_height = [0]  # total height of the stacked bars so far
    # stack each state on top of the previous ones
    for t in df[df['Day-Shift'] == d].itertuples():
        ax.bar((i,), (t.seconds), bottom=total_height, color=colors[t.State], label=t.State, linewidth=2, edgecolor='w')
        total_height = [total_height[0] + t.seconds]
# Add xticks with labels
ax.set_xticks(list(range(len(day_shifts))))
ax.set_xticklabels(day_shifts, rotation=45, ha='right')

# Create an unique legend, removing duplicates
handles, labels = ax.get_legend_handles_labels()
by_label = OrderedDict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys(), bbox_to_anchor=(1, 1))

enter image description here

You have to add the following imports to your code:

import matplotlib.pyplot as plt
from collections import OrderedDict
Sign up to request clarification or add additional context in comments.

3 Comments

This is really great PieCot .I tried a lot of options to achieve this but couldn't able to succeed. Thanks a lot, dude. Do you know how to fix the colors manually for labels?ex: Red for 'stopped' ,Yellow for 'A'
Also, your comments are really helpful to understand the code, Really appreciate it!!!!!!!!
You can manually create the dict colors, choosing for ech State value the color you prefer. For example, colors = {'STOPPED: 'r', 'A': 'y', ...}

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.