How to get stacked bar chart rows share the same axis

42 views Asked by At

I have a stacked horizontal bar chart using matplotlib.pyplot. It produces the following output: enter image description here

I wanted the x-axis width to be 100%, so colours would occupy the same width as styles, assuming the individual segments would be wider, to expand into the vacant space.

I thought filling a numpy array with equal values divided by 100 would ensure the values are proportionally scaled.

However, as per the output colours do not expand out.

Could anyone kindly point me in the direction of solving this problem?

Here is the code for a reproducible example.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rcParams.update(plt.rcParamsDefault)

dummy = {
    'colours': ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven'],
    'style': ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', '13', '14']
}

df = pd.DataFrame.from_dict(dummy, orient="index")

y_labels_colors = df.loc["colours"].dropna().tolist()
y_values_colors = np.full(len(y_labels_colors), len(y_labels_colors) / 100)

y_labels_styles = df.loc["style"].dropna().tolist()
y_values_styles = np.full(len(y_labels_styles), len(y_labels_styles) / 100)

fig, ax = plt.subplots(figsize=(12, 1))

cumulative_size_colors = 0
cumulative_size_styles = 0

for label, value in zip(y_labels_colors, y_values_colors):
    ax.barh("colours", value, left=cumulative_size_colors, color='lightskyblue', edgecolor='white', linewidth=1)
    cumulative_size_colors += value
    ax.text(cumulative_size_colors - value / 2, 0, label, ha='center', va='center')

for label, value in zip(y_labels_styles, y_values_styles):
    ax.barh("styles", value, left=cumulative_size_styles, color='lightsteelblue', edgecolor='white', linewidth=1)
    cumulative_size_styles += value
    ax.text(cumulative_size_styles - value / 2, 1, label, ha='center', va='center')

ax.set_frame_on(False)
ax.set_xticks([])

plt.show()

1

There are 1 answers

0
dimButTries On BEST ANSWER

I resolve this by modifying: From:

y_values_colors = np.full(len(y_labels_colors), len(y_labels_colors) / 100)
y_values_styles = np.full(len(y_labels_styles), len(y_labels_styles) / 100)

To:

y_values_colors = np.full(len(y_labels_colors), 1 / len(y_labels_colors))
y_values_styles = np.full(len(y_labels_styles), 1 / len(y_labels_styles))
``

By adjusting y_values_colors and y_values_styles to have equal values (1 divided by the number of items in each category). This ensures the space is evenly distributed for both "colours" and "styles" in the stacked bar chart.