How can I create a bar plot with rounded corners, like shown in this image? Can it be done with matplotlib?
It looks like there's no way to directly add rounded corners to a bar chart. But matplotlib does provide a FancyBboxPatch
class a demo of which is available here.
So in order to create a plot like shown in the question we could first make a simple horizontal bar chart:
import pandas as pd
import numpy as np
# make up some example data
np.random.seed(0)
df = pd.DataFrame(np.random.uniform(0,20, size=(4,4)))
df = df.div(df.sum(1), axis=0)
# plot a stacked horizontal bar chart
ax = df.plot.barh(stacked=True, width=0.98, legend=False)
ax.figure.set_size_inches(6,6)
This produces the following plot:
In order to make the rectangles have rounded corners we could go through every rectangle patch in ax.patches
and replace it with a FancyBboxPatch
. This new fancy patch with rounded corners copies location and color from the old patch so that we don't have to worry about placement.
from matplotlib.patches import FancyBboxPatch
ax = df.plot.barh(stacked=True, width=1, legend=False)
ax.figure.set_size_inches(6,6)
new_patches = []
for patch in reversed(ax.patches):
bb = patch.get_bbox()
color=patch.get_facecolor()
p_bbox = FancyBboxPatch((bb.xmin, bb.ymin),
abs(bb.width), abs(bb.height),
boxstyle="round,pad=-0.0040,rounding_size=0.015",
ec="none", fc=color,
mutation_aspect=4
)
patch.remove()
new_patches.append(p_bbox)
for patch in new_patches:
ax.add_patch(patch)
This is what we get then:
I gave the boxes a negative padding so that there are gaps between bars. The numbers are a bit of black magic. No idea what the unit is for rounding_size
and pad
. The mutation_aspect
is shown in the last demo example, here I set it to 4 because y
range is about 4 while x
range is approximately 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With