Matplotlib cycler doesn't work with hatches

Viewed 26

Given the following example

%matplotlib notebook

import matplotlib.pyplot as plt
from cycler import cycler

bar_cycler = (cycler(color=["#E69F00", "#56B4E9"]) +
             cycler(hatch=["/" , "o"]))

plt.rc("axes", prop_cycle=bar_cycler)


data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}

df = pd.DataFrame(data)

df.plot(stacked=True, kind='bar')

This produces the following image, i.e., it works for the color but doesn't take the hatching into account.

enter image description here

How do I make cyclers and hatching work?

1 Answers

Not all kind of plot can use hatch and maybe this is problem.

But you can plot it using two bar()

import matplotlib.pyplot as plt
import pandas as pd

data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}

df = pd.DataFrame(data)

fig, ax = plt.subplots()
ax.bar(["1","2","3"], df['calories'], hatch='/', color="#E69F00")
ax.bar(["1","2","3"], df['duration'], hatch='*', color="#56B4E9", bottom=df['calories'])

plt.show()

enter image description here


Matplotlib documentation: Stacked bar chart, Hatch demo, Hatch style reference


EDIT:

I found similar question and one answer uses the same method with two bar() but other answer sets hatch after drawing bars.

python - matplotlib: assigning different hatch to bars - Stack Overflow

And I made version which set hatch after drawing but I used itertool.cycle because it was more useful in this situation.

Every bar() creates many Rectangles which are in BarContainer and this need nested for-loops.

import pandas as pd
import matplotlib.pyplot as plt
from cycler import cycler

bar_cycler = cycler(color=["#E69F00", "#56B4E9"])
             
plt.rc("axes", prop_cycle=bar_cycler)

data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}

df = pd.DataFrame(data)

ax = df.plot(stacked=True, kind='bar')

# ---

import itertools

cycle_hatch = itertools.cycle(["/" , "o"])

for container, hatch in zip(ax.containers, cycle_hatch):
    for item in container.patches:
        item.set_hatch(hatch)
    
# ---     

plt.show()

EDIT:

Other similar question - but it set different hatch for every Rectangle in BarContainer.

python - How to to add stacked bar plot hatching in pandas? (...or how to get BarContainer vs AxisSubplot in pandas plot vs. matplotlib?) - Stack Overflow

Related