'Pyplot bar chart does not match table columns position with all bars
I'm building a bar graph with a table using the code example.
Everything looks good when I have up to 10 columns, but above 10 columns the bars are shifted to the left and do not match the position of the table columns. This happens only with odd number of columns/bars (e.g. 11 and 13, but not with 12 and 14 which looks good). It looks like the x-axis for columns 11 and 13 keeps space for columns 12 and 14. I've enclosed the code changes that I've made to the above example in order to reproduce the problem with.
I've been struggling with this for too long and did not find anything on the web, so I will appreciate any help.
The modified contents from the example:
data = [[ 66386, 174296, 75131, 577908, 32015, 66386, 174296, 75131, 577908, 32015, 100000, 75131, 174296],
[ 58230, 381139, 78045, 99308, 160454, 58230, 381139, 78045, 99308, 160454, 100000, 75131, 174296],
[ 89135, 80552, 152558, 497981, 603535, 89135, 80552, 152558, 497981, 603535, 100000, 75131, 174296],
[ 78415, 81858, 150656, 193263, 69638, 78415, 81858, 150656, 193263, 69638, 100000, 75131, 174296],
[ 139361, 331509, 343164, 781380, 52269, 139361, 331509, 343164, 781380, 52269, 100000, 75131, 174296]]
colLabels = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail', 'Freeze2', 'Wind2', 'Flood2', 'Quake2', 'Hail2', '11th', "12th", "13th")
Solution 1:[1]
Make sure you specify the xlim:
xlim(0,len(colLabels))

If you don't, then matplotlib will autoscale the x-axis, which is not what you want in this case, as the table underneath the plot is tied to the location of the actual bars.
Solution 2:[2]
The previous answer is outdated and does not really work. In your example, you need to do two things.
Change
index = np.arange(len(columns)) + 0.3toindex = np.arange(len(columns)).Add
plt.xlim([-0.5, len(colLabels)-0.5])
import numpy as np
import matplotlib.pyplot as plt
data = [[ 66386, 174296, 75131, 577908, 32015, 66386, 174296, 75131, 577908, 32015, 100000, 75131, 174296],
[ 58230, 381139, 78045, 99308, 160454, 58230, 381139, 78045, 99308, 160454, 100000, 75131, 174296],
[ 89135, 80552, 152558, 497981, 603535, 89135, 80552, 152558, 497981, 603535, 100000, 75131, 174296],
[ 78415, 81858, 150656, 193263, 69638, 78415, 81858, 150656, 193263, 69638, 100000, 75131, 174296],
[ 139361, 331509, 343164, 781380, 52269, 139361, 331509, 343164, 781380, 52269, 100000, 75131, 174296]]
colLabels = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail', 'Freeze2', 'Wind2', 'Flood2', 'Quake2', 'Hail2', '11th', "12th", "13th")
columns = colLabels
rows = ['%d year' % x for x in (100, 50, 20, 10, 5)]
values = np.arange(0, 2500, 500)
value_increment = 1000
# Get some pastel shades for the colors
colors = plt.cm.BuPu(np.linspace(0, 0.5, len(rows)))
n_rows = len(data)
#index = np.arange(len(columns)) + 0.3
index = np.arange(len(columns))
print(index)
bar_width = 0.4
# Initialize the vertical-offset for the stacked bar chart.
y_offset = np.zeros(len(columns))
fig, ax = plt.subplots(figsize=(15, 10))
# Plot bars and create text labels for the table
cell_text = []
for row in range(n_rows):
plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[row])
y_offset = y_offset + data[row]
cell_text.append(['%1.1f' % (x / 1000.0) for x in y_offset])
# Reverse colors and text labels to display the last value at the top.
colors = colors[::-1]
cell_text.reverse()
plt.xlim([-0.5, len(colLabels)-0.5])
# Add a table at the bottom of the axes
the_table = ax.table(cellText=cell_text,
rowLabels=rows,
rowColours=colors,
colLabels=columns,
loc='bottom')
plt.subplots_adjust(left=0.2, bottom=0.2)
plt.ylabel("Loss in ${0}'s".format(value_increment), fontsize=15)
plt.yticks(values * value_increment, ['%d' % val for val in values], fontsize=13)
plt.xticks([])
plt.title('Loss by Disaster', fontsize=15)
plt.show()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Ka-Wa Yip |

