Reputation: 22397
I am trying to have multiple of imshow rows in one side, and having only the colormap on the (right) side, without having this large white area.
import numpy as np
import matplotlib.pyplot as plt
font = {'family' : 'sans-serif',
'color' : 'k',
'weight' : 'normal',
'size' : 12,
}
x = "0.2, 0.3, 0.4, 0.5, 0.6".split(",")
y = "180, 175, 170, 169, 150".split(",")
z = [[5000, 4800, 4500, 4450, 4300]]
colors = ('b', 'g', 'r', 'c', 'm', 'y', 'k')
#ax1 = plt.subplot2grid((2,2), (0,0), rowspan=2)
#ax2 = plt.subplot2grid((2,2), (0,1))
#ax3 = plt.subplot2grid((2,2), (1,1))
image = np.random.rand(4,4)
axisNum = 0
numRows = 8
#plt.subplots_adjust(left = 0.125, right = 0.9, bottom = 0.1, top = 0.9, wspace = 0.2, hspace = 1)
plt.subplots_adjust(hspace = .5)
for i in range(numRows):
ax = plt.subplot2grid((numRows,2), (axisNum,0), aspect='equal')
im = ax.imshow(z, cmap=plt.cm.Blues, interpolation='nearest')
xticks = ax.get_xticks()
top_lables_width_spacings = 0.8
top_lables_hight_spacings = -.55
for i in range(len(y)):
ax.text(xticks[i] + top_lables_width_spacings, top_lables_hight_spacings, y[i], fontdict=font)
#ax1.set_aspect('auto')
#fig.colorbar(im, orientation='vertical')
ax.set_xticks(np.arange(len(x)), minor=False)
ax.set_xticklabels(x, minor=False)
ax.tick_params(labelbottom='on',labeltop='off', labelleft="off")
if axisNum == 0: plt.title('Avg. (s)\n', size=13)
ax.set_yticklabels([])
if axisNum != numRows-1: ax.set_xticklabels([])
elif axisNum == numRows-1: # the last axes
ax2 = plt.subplot2grid((numRows,2), (0,1), rowspan=numRows)
plt.colorbar(im)
axisNum += 1
plt.show()
As you can see from this code, I've used the mappable data from the last imshow axes, and then used colormap to represent it.
Upvotes: 0
Views: 428
Reputation: 23500
If you do not like it, delete it...
In your sample figure you have 10 different axes (you can check this by plt.gcf().get_axes()
). Of these 8 first are the plots you have drawn, 9th is the big white area, and 10th the colorbar itself.
So, you want to remove the second last axes:
# in case you do not have the `figure` instance at hand
fig = plt.gcf()
fig.delaxis(fig.get_axes()[-2])
Now the ugly white area is gone. Then you have the problem that the remaining axes do not fill the space. This is then a bit trickier, because you have many constraints. You can tweak the positions manually, but that'll results in a lot of work.
A better method is to:
So with your code (I modified the code in some other places, as well, just to guess what you might want):
import numpy as np
import matplotlib.pyplot as plt
x = "0.2, 0.3, 0.4, 0.5, 0.6".split(",")
y = "180, 175, 170, 169, 150".split(",")
z = [[5000, 4800, 4500, 4450, 4300]]
numRows = 8
fig, subaxes = plt.subplots(nrows=numRows, ncols=1)
axeslist = subaxes.flatten()
for ax in axeslist:
im = ax.imshow(z, cmap=plt.cm.Blues, interpolation='nearest')
ax.tick_params(labelbottom='off',labeltop='off', labelleft="off", labelright='off',
bottom='off', top='off', left='off', right='off')
if ax == axeslist[0]:
ax.set_title('Avg. (s)\n', size=13)
ax.tick_params(top='on', labeltop='on')
ax.set_xticks(range(len(y)))
ax.set_xticklabels(y)
elif ax == axeslist[-1]:
ax.tick_params(bottom='on', labelbottom='on')
ax.set_xticks(range(len(x)))
ax.set_xticklabels(x)
# make sure the existing subplots only take 80 % of the image
fig.subplots_adjust(right=.8)
# this uses the last image
# and creates new axes for the colorbar
fig.colorbar(im, cax = fig.add_axes([0.85, 0.1, 0.05, 0.8]))
plt.show()
This gives:
There are still some unnecessary spaces, but they are difficult to avoid, if you want to keep aspect='equal'
with your images, as then the horizontal size of your subplots is fixed by the vertical size.
If you are ready to give that up the square pixels, then by saying:
im = ax.imshow(z, cmap=plt.cm.Blues, interpolation='nearest', aspect='auto')
You will get:
Upvotes: 1