Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bar chart with rounded corners in Matplotlib?

How can I create a bar plot with rounded corners, like shown in this image? Can it be done with matplotlib?

bar chart with rounded corners

like image 321
Markus Avatar asked Oct 17 '19 05:10

Markus


1 Answers

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:

a plot with regular rectangles

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:

plot with rounded rectangles

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.

like image 116
gereleth Avatar answered Nov 08 '22 21:11

gereleth