Issue
This is in connection to my earlier question with the link here: How do I add labels and trace lines into my grouped bar graph?
The dataframe used is the same.
I have decided to use this code in order to label my group bar graph. It produces a graph with all bars annotated with the correct data. However, it ended up like this:
I have even tried plt.figure(figsize()) to resize my graph to no avail.
Is there an explanation into why only 2 boxes were displayed for each x-axis ticks and is there a way to resolve this? Thanks!
This is my code to refer to:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv(r'C:\Users\admin\Desktop\Customer_list_practice.csv')
months = df.columns.values.tolist()
months = months[1:]
# Increase size of plot in jupyter
plt.figure(figsize=[15,14])
labels = months
cus_1 = list(df.loc[0])
cus_1 = cus_1[1:]
cus_2 = list(df.loc[1])
cus_2 = cus_2[1:]
cus_3 = list(df.loc[2])
cus_3 = cus_3[1:]
# Increase size of plot in jupyter
plt.rcParams["figure.figsize"] = (10,10)
x = np.arange(len(labels)) # the label locations
width = 0.20 # the width of the bars
fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, cus_1, width, label='1')
rects2 = ax.bar(x + width/2, cus_2, width, label='2')
rects3 = ax.bar(x - width/2, cus_3, width, label='3')
# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Sales (S$)')
ax.set_title('Sales from each customers')
ax.set_xticks(x, labels)
ax.legend()
ax.bar_label(rects1, padding=3)
ax.bar_label(rects2, padding=3)
ax.bar_label(rects3, padding=3)
fig.tight_layout()
plt.legend(bbox_to_anchor=(-0.05,1), loc=1, prop={'size': 19})
plt.show()
Solution
The reason for the overlap is because of the code in the rects1/2/3
- these are basically plotting the rectangles required. In your code, you have them as x - width/2
, x + width/2
and x - width/2
. As you can see, the x-coordinates for the blue bar is the same as the green one, which is causing the bars to be plotted on top of each other. So, they should be x - width/2
, x
and x + width/2
.
Once fixed, the bar width becomes an issue as they will overlap on each other because of the size. So, I reduced the width from 0.5 to 0.3. I think you can go as high as 0.33 without overlapping, but will leave it up to you.
The updated code and output is below. Note that my version of matplotlib doesn't allow bar_level
, so have commented it. You can adjust that if you need to.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.read_csv(r'C:\Users\admin\Desktop\Customer_list_practice.csv')
months = df.columns.values.tolist()
months = months[1:]
# Increase size of plot in jupyter
plt.figure(figsize=[15,14])
labels = months
cus_1 = list(df.loc[0])
cus_1 = cus_1[1:]
cus_2 = list(df.loc[1])
cus_2 = cus_2[1:]
cus_3 = list(df.loc[2])
cus_3 = cus_3[1:]
# Increase size of plot in jupyter
plt.rcParams["figure.figsize"] = (10,10)
x = np.arange(len(labels)) # the label locations
width = 0.30 # the width of the bars
print("x = ", x)
fig, ax = plt.subplots()
rects1 = ax.bar(x - width, cus_1, width, label='1')
rects2 = ax.bar(x, cus_2, width, label='2')
rects3 = ax.bar(x + width, cus_3, width, label='3')
# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Sales (S$)')
ax.set_title('Sales from each customers')
ax.set_xticks(x, labels)
ax.legend()
#ax.bar_label(rects1, padding=3)
#ax.bar_label(rects2, padding=3)
#ax.bar_label(rects3, padding=3)
fig.tight_layout()
plt.show()
Output plot
Answered By - Redox
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.