0

This is my current output: enter image description here Now i want the next bars next to the already plotted bars.

My DataFrame has 3 columns: 'Block', 'Cluster', and 'District'.

'Block' and 'Cluster' contain the numbers for plotting and the grouping is based on the strings in 'District'.

How can I plot the other bars next to the existing bars?

df=pd.read_csv("main_ds.csv")
fig = plt.figure(figsize=(20,8))
ax = fig.add_subplot(111)
plt.xticks(rotation=90)
bwidth=0.30
indic1=ax.bar(df["District"],df["Block"], width=bwidth, color='r')
indic2=ax.bar(df["District"],df["Cluster"], width=bwidth, color='b')
ax.autoscale(tight=False)

def autolabel(rects):
    for rect in rects:
        h = rect.get_height()
        ax.text(rect.get_x()+rect.get_width()/2., 1.05*h, '%d'%int(h),
                ha='center', va='top')
autolabel(indic1)
autolabel(indic2)
plt.show()

Data:

District Block Cluster Villages Schools Decadal_Growth_Rate Literacy_Rate Male_Literacy Female_Literacy Primary ... Govt_School Pvt_School Govt_Sch_Rural Pvt_School_Rural Govt_Sch_Enroll Pvt_Sch_Enroll Govt_Sch_Enroll_Rural Pvt_Sch_Enroll_Rural Govt_Sch_Teacher Pvt_Sch_Teacher 0 Dimapur 5 30 278 494 23.2 85.4 88.1 82.5 147 ... 298 196 242 90 33478 57176 21444 18239 3701 3571 1 Kiphire 3 3 94 142 -58.4 73.1 76.5 70.4 71 ... 118 24 118 24 5947 7123 5947 7123 853 261 2 Kohima 5 5 121 290 22.7 85.6 89.3 81.6 128 ... 189 101 157 49 10116 26464 5976 8450 2068 2193 3 Longleng 2 2 37 113 -30.5 71.1 75.6 65.4 60 ... 90 23 90 23 3483 4005 3483 4005 830 293 4 Mon 5 5 139 309 -3.8 56.6 60.4 52.4 165 ... 231 78 219 58 18588 16578 17108 8665 1667 903 5 rows × 26 columns

9
  • is the upper picture your goal or your current output? If it is the goal: what is the outcome right now? Else: Do you want stacked bars? Commented Aug 24, 2020 at 6:11
  • the upper picture is my current output. I want the second bar stacked next to it... Commented Aug 24, 2020 at 6:14
  • ah ok, so grouped bar charts Commented Aug 24, 2020 at 6:16
  • another thing is notice that the values of the bar isn't sitting nicely on top of the bar charts. It's all over the place... Commented Aug 24, 2020 at 6:17
  • what do you mean with 'District' is text. Is the content still a number but in string format? Commented Aug 24, 2020 at 6:21

2 Answers 2

1

Try using pandas.DataFrame.plot

import pandas as pd
import numpy as np
from io import StringIO
from datetime import date
import matplotlib.pyplot as plt

def add_value_labels(ax, spacing=5):
    for rect in ax.patches:
        y_value = rect.get_height()
        x_value = rect.get_x() + rect.get_width() / 2

        space = spacing
        # Vertical alignment for positive values
        va = 'bottom'

        # If value of bar is negative: Place label below bar
        if y_value < 0:
            # Invert space to place label below
            space *= -1
            # Vertically align label at top
            va = 'top'

        # Use Y value as label and format number with one decimal place
        label = "{:.1f}".format(y_value)

        # Create annotation
        ax.annotate(
            label,                      # Use `label` as label
            (x_value, y_value),         # Place label at end of the bar
            xytext=(0, space),          # Vertically shift label by `space`
            textcoords="offset points", # Interpret `xytext` as offset in points
            ha='center',                # Horizontally center label
            va=va)                      # Vertically align label differently for
                                        # positive and negative values.

first3columns = StringIO("""District    Block   Cluster
Dimapur 5   30
Kiphire 3   3
Kohima  5   5
Longleng    2
Mon 5   5
""")

df_plot = pd.read_csv(first3columns, delim_whitespace=True)


fig, ax = plt.subplots()


#df_plot.set_index(['District'], inplace=True)
df_plot[['Block', 'Cluster']].plot.bar(ax=ax, color=['r', 'b'])
ax.set_xticklabels(df_plot['District'])

add_value_labels(ax)

plt.show()

enter image description here

Sign up to request clarification or add additional context in comments.

8 Comments

Here, df_plot = pd.DataFrame({ 'District': [date(2020,8,19), date(2020,8,20), date(2020,8,21), date(2020,8,22)], 'Block': [2,15,2,7], 'Cluster': [0,2,11,0] }) Can i do df["District"] instead as i am reading it from a csv file?
@OchenAo You didn't give your data, so I generate some by my own to show how the plot looks like using my code. The logic of my code has nothing to do with the data.
@OchenAo Sure you can. You only need to replace my df_plot defination with df_plot = pd.read_csv("main_ds.csv").
KeyError: "None of ['District'] are in the columns"
@OchenAo See my updated answer. I avoid to use df_plot.set_index(['District'], inplace=True).
|
0

Try changing

indic1=ax.bar(df["District"],df["Block"], width=bwidth, color='r')
indic2=ax.bar(df["District"],df["Cluster"], width=bwidth, color='b')

to

indic1=ax.bar(df["District"]-bwidth/2,df["Block"], width=bwidth, color='r')
indic2=ax.bar(df["District"]+bwidth/2,df["Cluster"], width=bwidth, color='b')

5 Comments

Nope, it doesn't seem to be stacking next to it but rather over it..
And how do you see now? Please, provide some data to replicate it (print(df.head())).
TypeError: unsupported operand type(s) for -: 'str' and 'float'
District Block Cluster Villages Schools Decadal_Growth_Rate Literacy_Rate Male_Literacy Female_Literacy Primary ... Govt_School Pvt_School Govt_Sch_Rural Pvt_School_Rural Govt_Sch_Enroll Pvt_Sch_Enroll Govt_Sch_Enroll_Rural Pvt_Sch_Enroll_Rural Govt_Sch_Teacher Pvt_Sch_Teacher 0 Dimapur 5 30 278 494 23.2 85.4 88.1 82.5 147 ... 298 196 242 90 33478 57176 21444 18239 3701 3571 1 Kiphire 3 3 94 142 -58.4 73.1 76.5 70.4 71 ... 118 24 118 24 5947 7123 5947 7123 853 261 2 Kohima 5 5 121 290 22.7 85.6 89.3 81.6 128 ... 189 101 157 49 10116 26464 5976 8450 2068 2193
df["District"] is a text string so you can't do a math operand on it, i suppose....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.