Reputation: 107
How to add another ax to a plot on the right corner in this code given here
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
# Fixing random state for reproducibility
np.random.seed(19680801)
# the random data
x = np.random.randn(1000)
y = np.random.randn(1000)
fig, axScatter = plt.subplots(figsize=(5.5, 5.5))
# the scatter plot:
axScatter.scatter(x, y)
axScatter.set_aspect(1.)
# create new axes on the right and on the top of the current axes
# The first argument of the new_vertical(new_horizontal) method is
# the height (width) of the axes to be created in inches.
divider = make_axes_locatable(axScatter)
axHistx = divider.append_axes("top", 1.2, pad=0.1, sharex=axScatter)
axHisty = divider.append_axes("right", 1.2, pad=0.1, sharey=axScatter)
# make some labels invisible
axHistx.xaxis.set_tick_params(labelbottom=False)
axHisty.yaxis.set_tick_params(labelleft=False)
# now determine nice limits by hand:
binwidth = 0.25
xymax = max(np.max(np.abs(x)), np.max(np.abs(y)))
lim = (int(xymax/binwidth) + 1)*binwidth
bins = np.arange(-lim, lim + binwidth, binwidth)
axHistx.hist(x, bins=bins)
axHisty.hist(y, bins=bins, orientation='horizontal')
# the xaxis of axHistx and yaxis of axHisty are shared with axScatter,
# thus there is no need to manually adjust the xlim and ylim of these
# axis.
axHistx.set_yticks([0, 50, 100])
axHisty.set_xticks([0, 50, 100])
plt.draw()
plt.show()
So that the resulting image is something like this
I tried to add another axis by using::
ax_cnr = divider.append_axes("right", 1.2, pad=0.1)
But it is not giving the desired output!!
Kindly help!
Upvotes: 1
Views: 982
Reputation: 499
The answer above using plt.subplots_mosaic
is a good answer but I believe suplots_mosaic is currently an experimental/provisional API so I wanted to offer a solution using plt.subplots()
and manipulating the axes using gridspec_kw
:
import numpy as np
import matplotlib.pyplot as plt
# Fixing random state for reproducibility
np.random.seed(19680801)
# the random data
x = np.random.randn(1000)
y = np.random.randn(1000)
# Start figure
fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(5.5, 5.5), sharex='col', sharey='row', gridspec_kw={'height_ratios': [1, 3], 'width_ratios': [3, 1], 'hspace': 0.05, 'wspace': 0.05})
# Define/name each axes
axScatter = axs[1, 0] # bottom left
axHistx = axs[0, 0] # top left
axHisty = axs[1, 1] # bottom right
new_axis = axs[0, 1] # new axis - top right
# the scatter plot:
axScatter.scatter(x, y)
axScatter.set_aspect(1.)
# make some labels invisible
axHistx.xaxis.set_tick_params(labelbottom=False)
axHisty.yaxis.set_tick_params(labelleft=False)
# now determine nice limits by hand:
binwidth = 0.25
xymax = max(np.max(np.abs(x)), np.max(np.abs(y)))
lim = (int(xymax/binwidth) + 1)*binwidth
bins = np.arange(-lim, lim + binwidth, binwidth)
axHistx.hist(x, bins=bins)
axHisty.hist(y, bins=bins, orientation='horizontal')
# Hist axes
axHistx.set_yticks([0, 50, 100])
axHisty.set_xticks([0, 50, 100])
plt.draw()
plt.show()
Here is the result: Figure with new axes.
You can find more info about manipulating axes in Matplotlib's Axes Tutorial (https://matplotlib.org/stable/tutorials/intermediate/arranging_axes.html).
Upvotes: 2
Reputation: 177
I don't know about the make_axes_locatable
code directly, but one could work around this with a mosaic
like so:
import numpy as np
import matplotlib.pyplot as plt
# Fixing random state for reproducibility
np.random.seed(19680801)
# the random data
x = np.random.randn(1000)
y = np.random.randn(1000)
fig, axs = plt.subplot_mosaic([['a)', 'a)', 'd)'],
['b)', 'b)', 'c)'],
['b)', 'b)', 'c)']],
constrained_layout=True)
axs['b)'].scatter(x, y)
# make some labels invisible
axs['a)'].xaxis.set_tick_params(labelbottom=False)
axs['c)'].yaxis.set_tick_params(labelleft=False)
axs['d)'].xaxis.set_tick_params(labelbottom=False)
axs['d)'].yaxis.set_tick_params(labelleft=False)
# now determine nice limits by hand:
binwidth = 0.25
xymax = max(np.max(np.abs(x)), np.max(np.abs(y)))
lim = (int(xymax/binwidth) + 1)*binwidth
bins = np.arange(-lim, lim + binwidth, binwidth)
axs['a)'].hist(x, bins=bins)
axs['c)'].hist(y, bins=bins, orientation='horizontal')
axs['a)'].set_yticks([0, 50, 100])
axs['c)'].set_xticks([0, 50, 100])
axs['b)'].set_xticks([-4, -2, 0, 2, 4])
axs['b)'].set_yticks([-4, -2, 0, 2, 4])
which shows something similar to the original:
the 'd)'
axis is accessible with just axs['d)'].<do stuff here>()
Sorry about the obscure naming, I copypasted a mosaic example from here and worked from that.
Upvotes: 1