I have looked around to no avail, but I'm having an issue that my python GridSpec multiplot keeps changing the axes. The main issue is that even though I explicitly set the extent and aspect of the 2dheatmap, it still changes the xaxis so that I have white space around my graph.
I have tried turning autoscale off but this causes the flanking histograms to go wrong, presumably because of the shared axis?
def hist2d_flanking1d(x, y, xlims, ylims, bins=50,
weights=None,xlabel="xlabel", ylabel="ylabel", cbarlabel='Testing'):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter, MaxNLocator
from numpy import linspace
import matplotlib.gridspec as gridspec
from matplotlib import cm as cm
import pdb
from matplotlib import ticker
from mpl_toolkits.axes_grid1 import make_axes_locatable
plt.close('all')
fig = plt.figure()
gs = gridspec.GridSpec(2,2, width_ratios=[3,1], height_ratios=[1,3])
axTemperature = plt.subplot(gs[1,0])
# Find the min/max of the data
xmin = np.float(xlims[0])
xmax = np.float(xlims[1])
ymin = np.float(ylims[0])
ymax = np.float(ylims[1])
xbins = linspace(start = xmin, stop = xmax, num = bins)
ybins = linspace(start = ymin, stop = ymax, num = bins)
H, xedges,yedges = np.histogram2d(y,x,bins=(ybins,xbins), weights=weights)
extent=[xmin,xmax,ymin,ymax]
cax = (axTemperature.imshow(H, extent=extent,
interpolation='nearest', origin='lower',aspect=((xmax-xmin)/(ymax-ymin)),
cmap=cm.cubehelix_r))
#Set up the plot limits
axTemperature.set_xlim(xmin,xmax)
axTemperature.set_ylim(ymin,ymax)
axTemperature.set_xlabel(xlabel, fontsize=22, labelpad=20)
axTemperature.set_ylabel(ylabel, fontsize=22, labelpad=20)
#Make the tickmarks pretty
ticklabels = axTemperature.get_xticklabels()
for label in ticklabels:
label.set_fontsize(18)
ticklabels = axTemperature.get_yticklabels()
for label in ticklabels:
label.set_fontsize(18)
# Now setup the two flanking histograms
axHistx = plt.subplot(gs[0,0], sharex=axTemperature)
axHisty = plt.subplot(gs[1,1], sharey=axTemperature)
# Remove the inner axes numbers of the histograms
plt.setp(axHisty.get_yticklabels(), visible=False)
plt.setp(axHistx.get_xticklabels(), visible=False)
# Add labels
axHistx.set_ylabel('N', fontsize=22, labelpad=20)
axHisty.set_xlabel('N', fontsize=22, labelpad=20)
#Plot the histograms
axHistx.hist(x, bins=xbins, color = 'blue', histtype='step')
axHisty.hist(y, bins=ybins, orientation='horizontal', color ='red',histtype='step')
# Make the tickmarks pretty
ticklabels = axHistx.get_yticklabels()
for label in ticklabels:
label.set_fontsize(18)
# Make the tickmarks pretty
ticklabels = axHisty.get_xticklabels()
for label in ticklabels:
label.set_fontsize(18)
#Cool trick that changes the number of tickmarks for the histogram axes
axHisty.xaxis.set_major_locator(MaxNLocator(1))
axHistx.yaxis.set_major_locator(MaxNLocator(1))
# This should create an axes on the rightside of the vertical
# histogram. Width is argument 2, padding argument 3, reduce
# the number of ticks to make it less messy
divider = make_axes_locatable(axHisty)
extend = divider.append_axes("right", "20%", pad=0.2)
cb = plt.colorbar(cax, cax=extend)
tick_locator = ticker.MaxNLocator(nbins=5)
cb.locator = tick_locator
cb.update_ticks()
# Have to draw first, then tightlayout then draw again, otherwise
# the axes labels are cut off. If you do it before drawing it
# complains that CGContextRef is NULL
plt.draw()
gs.tight_layout(fig)
plt.draw()
return axTemperature, axHistx, axHisty
I can't show you the outcome because I don't have the reputation to upload images.
As an aside, I'm also having issue with changing the tick numbers, I have set set_major_locator(MaxNLocator(1))
which should ( I think ) only have the maximum value tick mark, but this isn't consistent. The top histogram works no problem, but the side histogram only has 0 on the axis.
I have done further investigation and have found that it breaks down after:
axHistx = plt.subplot(gs[0,0], sharex=axTemperature)
axHisty = plt.subplot(gs[1,1], sharey=axTemperature)
Though I'm not sure why this suddenly breaks the axis size for the previous code.