Reputation: 29
I'm generating a bar-chart with matplotlib. It all works well but I can't figure out how to prevent the labels of the axis from overlapping each other. Here an example:
#!/usr/bin/env python
import matplotlib.pyplot as plt
import matplotlib.ticker as tic
import csv
from numpy import *
import matplotlib.pyplot as plt
from numpy.random import normal
import numpy as np
target_LandQ=['CHEMBL1293235', 'CHEMBL220', 'CHEMBL289', 'CHEMBL2903', 'CHEMBL311', 'CHEMBL3199', 'CHEMBL3356', 'CHEMBL3397', 'CHEMBL340', 'CHEMBL3622', 'CHEMBL4078', 'CHEMBL5501', 'CHEMBL1075216', 'CHEMBL1075280', 'CHEMBL1075282', 'CHEMBL1798', 'CHEMBL1821', 'CHEMBL1824', 'CHEMBL1827', 'CHEMBL1832', 'CHEMBL1833', 'CHEMBL1835', 'CHEMBL1841', 'CHEMBL1867', 'CHEMBL1868', 'CHEMBL1889', 'CHEMBL1901', 'CHEMBL1909043', 'CHEMBL1909044', 'CHEMBL1914', 'CHEMBL1916', 'CHEMBL1941', 'CHEMBL1942', 'CHEMBL1951', 'CHEMBL1977', 'CHEMBL203', 'CHEMBL2034', 'CHEMBL2035', 'CHEMBL205', 'CHEMBL2056', 'CHEMBL206', 'CHEMBL210', 'CHEMBL211', 'CHEMBL213', 'CHEMBL216', 'CHEMBL217', 'CHEMBL218', 'CHEMBL219', 'CHEMBL221', 'CHEMBL222', 'CHEMBL223', 'CHEMBL224', 'CHEMBL225', 'CHEMBL226', 'CHEMBL228', 'CHEMBL2292', 'CHEMBL230', 'CHEMBL231', 'CHEMBL2327', 'CHEMBL233', 'CHEMBL234', 'CHEMBL236', 'CHEMBL237', 'CHEMBL238', 'CHEMBL240', 'CHEMBL2414', 'CHEMBL242', 'CHEMBL2434', 'CHEMBL245', 'CHEMBL246', 'CHEMBL248', 'CHEMBL2487', 'CHEMBL249', 'CHEMBL250', 'CHEMBL251', 'CHEMBL252', 'CHEMBL256', 'CHEMBL258', 'CHEMBL259', 'CHEMBL260', 'CHEMBL2622', 'CHEMBL273', 'CHEMBL274', 'CHEMBL287', 'CHEMBL299', 'CHEMBL3048', 'CHEMBL3072', 'CHEMBL315', 'CHEMBL3157', 'CHEMBL3198', 'CHEMBL321', 'CHEMBL3243', 'CHEMBL326', 'CHEMBL332', 'CHEMBL3371', 'CHEMBL3385', 'CHEMBL3403', 'CHEMBL3459', 'CHEMBL3464', 'CHEMBL3577', 'CHEMBL4015', 'CHEMBL4018', 'CHEMBL402', 'CHEMBL4029', 'CHEMBL4040', 'CHEMBL4071', 'CHEMBL4074', 'CHEMBL4358', 'CHEMBL4376', 'CHEMBL4445', 'CHEMBL4607', 'CHEMBL4608', 'CHEMBL4644', 'CHEMBL4768', 'CHEMBL4777', 'CHEMBL4780', 'CHEMBL4801', 'CHEMBL4822', 'CHEMBL5017', 'CHEMBL5077', 'CHEMBL5144', 'CHEMBL5281', 'CHEMBL5282', 'CHEMBL5486', 'CHEMBL5763']
hist_q=[1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
y_pos = np.arange(len(hist_q))
plt.barh(y_pos, hist_q, align='center', alpha=0.4)
plt.yticks(y_pos, target_LandQ)
plt.figure(1, [20, 20])
plt.xlabel('Target Presence')
plt.title('Query Molecule')
fig="s_Q"
plt.savefig(fig,bbox_inches='tight')
plt.show()
fig = plt.figure()
fig.clf()
ax = fig.add_subplot(111)
ax.yaxis.grid(True, linestyle='-', which='major', color='grey', alpha=0.5)
ind = range(len(hist_q))
rects = ax.bar(ind, hist_q, width=0.4444, align='center', color='thistle')
ax.set_xticks(ind)
ax.set_xticklabels(target_LandQ)
fig = plt.figure(1, [20, 8])
ax.set_xlim(-1,100)
plt.setp(ax.get_xticklabels(), fontsize=7, rotation='vertical')
fig.autofmt_xdate()
plt.savefig('test2.png', dpi = 300, pad_inches = 0)
plt.show()
Upvotes: 1
Views: 2772
Reputation: 20344
You need to do a few different bits here. Your overlapping is basically due to the fact that the labels are written in a font that, at the scale of your plot, is too large to fit within the height of the bars. Things you can do:
plt.figure()
right up front before you call plt.barh()
- that way the display size of the figure will be applied before you plot. In your case, you want a tall but not wide figure, try using size [5,20]
ylim
to your plot and set it to only the y
values you use so that you don't get white space above and below your bars6
point.Applying all these - your code would look like (e.g.):
... Your existing code up to...
y_pos = np.arange(len(hist_q))
plt.figure(1, [5, 20]) # this line moved and figure size changed to suit data
plt.ylim(0,max(y_pos)+1) # this gets rid of whitespace
plt.tick_params(axis='both', which='major', labelsize=6) # makes axis labels smaller
... Carry on existing code from plt.barh(y_pos, hist_q, align='center', alpha=0.4) ...
You can do the same for the x
axis on your second plot. These settings often take a bit of fiddling around to get the plot looking exactly how you want.
I wouldn't use fig
for the variable name to contain the string name of your figure to call savefig
. It will work fine, but makes your code hard to read, because fig
nearly always refers to a Figure
object in code using matplotlib
. Just a convention - your code is not wrong.
Upvotes: 1