Home > Software design >  How to merge common bars and labels in matplotlib bar plot
How to merge common bars and labels in matplotlib bar plot

Time:03-04

I want to create a barplot with these specifities:

  • No space between bars
  • Combine unique values of the common values of bars

There is no similar question!

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_axes([0,0,1,1])
langs = [1,2,3,4,5,6,7,8,9,10]
students = [10,10,20,20,20,20,30,30,15,15]
ax.bar(langs,students)
plt.savefig('barplot.pdf')

the output of code

ax.bar(langs,students,width = 1.0)

width = 1.0 is NOT EXACTLY working. There is little gaps, too.

I want to create the exact output below.

enter image description here

How can I do this?

CodePudding user response:

Seamless bars

Use width=1 and set both color and ec to the same color:

fig, ax = plt.subplots()

width = 1
color = 'blue'
ax.bar(langs, students, width=width, color=color, ec=color)
ax.set_ylim(0, 35)

Merged labels

Use pandas with

import matplotlib.pyplot as plt
import pandas as pd

fig, ax = plt.subplots()

langs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
students = [10, 10, 20, 20, 20, 20, 30, 30, 15, 15, 20, 20, 20]
#                                                   ^ another block of 20s

width = 1
color = 'blue'
ax.bar(langs, students, width=width, color=color, ec=color)
ax.set_ylim(0, 35)

df = pd.DataFrame(dict(langs=langs, students=students))
blocks = df.students.ne(df.students.shift()).cumsum()
labels = df.groupby(blocks, as_index=False)[['langs', 'students']].mean()
#    langs  students
# 0    1.5      10.0
# 1    4.5      20.0
# 2    7.5      30.0
# 3    9.5      15.0
# 4   12.0      20.0 <- repeated 20, so groupby('students') would not have worked

for x, y in zip(labels['langs'], labels['students']):
    ax.text(x, y   1, f'{y:.0f}', ha='center')
  • Related