Imshow And Plot Side By Side
Solution 1:
There are just so many ways to tackle this. All of the following will give more or less the same image
A. Reduce the available space
You may reduce the available space such that both plots are constrained to the same vertical margins. This can be done by
reducing figure height
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6,2.3), ...)
using
subplots_adjust
to limit the marginsfig.subplots_adjust(top=0.7, bottom=0.3)
B. Use InsetPosition
You may use mpl_toolkits.axes_grid1.inset_locator.InsetPosition
to adjust the coordinates of the second axes to match those of the first one.
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import InsetPosition
defvisualize(arr):
fig, (ax1, ax2) = plt.subplots(1, 2,
gridspec_kw = {'width_ratios': [1, 3]})
ax1.imshow(arr)
flat = arr.flatten()
x = flat[~np.isnan(flat)]
sns.distplot(x, ax=ax2)
ip = InsetPosition(ax1, [1.5,0,3,1])
ax2.set_axes_locator(ip)
plt.show()
arr = np.random.randn(200,120)
visualize(arr)
C. Use an axes divider
You may create only the axes for the image and then use mpl_toolkits.axes_grid1.make_axes_locatable
to create a new axes next to it.
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
def visualize(arr):
fig, ax = plt.subplots()
divider = make_axes_locatable(ax)
ax2 = divider.new_horizontal(size="300%", pad=0.5)
fig.add_axes(ax2)
ax.imshow(arr)
flat = arr.flatten()
x = flat[~np.isnan(flat)]
sns.distplot(x, ax=ax2)
plt.show()
arr = np.random.randn(200,120)
visualize(arr)
D. calculate the desired aspect ratio
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
defvisualize(arr):
gkw = {'width_ratios':[1, 3] }
fig, (ax1, ax2) = plt.subplots(1, 2, gridspec_kw = gkw )
ax1.imshow(arr)
flat = arr.flatten()
x = flat[~np.isnan(flat)]
sns.distplot(x, ax=ax2)
ya = np.diff(np.array(ax2.get_ylim()))[0]
xa = np.diff(np.array(ax2.get_xlim()))[0]
wa = gkw['width_ratios'][0]/float(gkw['width_ratios'][1])
ia = arr.shape[0]/float(arr.shape[1])
ax2.set_aspect(float(wa*ia/(ya/xa)))
plt.show()
arr = np.random.randn(200,120)
visualize(arr)
E. Dynamically copy positions
You may get the position of the left plot and copy its y-coordinates to the right subplot's position. This is a nice add-on to existing code. The drawback is necessary because subsequent changes to the figure size require to recalculate the positions.
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
defvisualize(arr):
gkw = {'width_ratios':[1, 3] }
fig, (ax1, ax2) = plt.subplots(1, 2, gridspec_kw = gkw )
ax1.imshow(arr)
flat = arr.flatten()
x = flat[~np.isnan(flat)]
sns.distplot(x, ax=ax2)
defon_resize(evt=None):
ax1.apply_aspect()
bb1 = ax1.get_position()
bb2 = ax2.get_position()
bb2.y0 = bb1.y0; bb2.y1 = bb1.y1
ax2.set_position(bb2)
fig.canvas.mpl_connect("resize_event", on_resize)
on_resize()
plt.show()
arr = np.random.randn(200,120)
visualize(arr)
Post a Comment for "Imshow And Plot Side By Side"