I'd like to have four plots with images. All channels, and one for Red, Green and Blue channel. For RGB I'd like to plot a color profile across columns and rows. I would like to have the profile plots aligned exactly to the corresponding image. I mean their width and length should match to width and length, of an image. Their heights should be equal.
For now I achieved this effect using GridSpec
. I know I can manipualte by changing fig size proportions, but it is not the solution. I need exact fit.
Here is my code.
def show_signal_across_image(self):
fig = plt.figure(figsize=(8, 9), dpi=109)
gs = GridSpec(4, 4,
height_ratios=[10, 2, 10, 2],
width_ratios=[10, 2, 10, 2],
left=0.05,
right=1 - 0.03,
top=0.95,
bottom=0.06,
hspace=0.3,
wspace=0.4)
ax_all = fig.add_subplot(gs[0])
ax_red_img = fig.add_subplot(gs[2])
ax_green_img = fig.add_subplot(gs[8])
ax_blue_img = fig.add_subplot(gs[10])
ax_red_signal_horizontal = fig.add_subplot(gs[6], sharex=ax_red_img)
ax_red_signal_vertical = fig.add_subplot(gs[3], sharey=ax_red_img)
ax_green_signal_horizontal = fig.add_subplot(gs[12], sharex=ax_green_img)
ax_green_signal_vertical = fig.add_subplot(gs[9], sharey=ax_green_img)
ax_blue_signal_horizontal = fig.add_subplot(gs[14], sharex=ax_blue_img)
ax_blue_signal_vertical = fig.add_subplot(gs[11], sharey=ax_blue_img)
signals = self.get_signal_values()
red_horizontal, red_vertical, green_horizontal, green_vertical, blue_horizontal, blue_vertical = signals
horizontal_signals = [red_horizontal, green_horizontal, blue_horizontal]
vertical_signals = [red_vertical, green_vertical, blue_vertical]
max_value_horizontal = max([item for sublist in horizontal_signals for item in sublist])
max_value_vertical = max([item for sublist in vertical_signals for item in sublist])
ax_red_signal_horizontal.plot(red_horizontal)
ax_green_signal_horizontal.plot(green_horizontal)
ax_blue_signal_horizontal.plot(blue_horizontal)
ax_red_signal_vertical.plot(red_vertical, np.arange(len(red_vertical)))
ax_green_signal_vertical.plot(green_vertical, np.arange(len(green_vertical)))
ax_blue_signal_vertical.plot(blue_vertical, np.arange(len(blue_vertical)))
ax_red_signal_vertical.invert_xaxis()
ax_green_signal_vertical.invert_xaxis()
ax_blue_signal_vertical.invert_xaxis()
for ax in [ax_red_signal_horizontal, ax_green_signal_horizontal, ax_blue_signal_horizontal]:
ax.set_ylim(0, max_value_horizontal * 1.1)
for ax in [ax_red_signal_vertical, ax_green_signal_vertical, ax_blue_signal_vertical]:
ax.set_xlim(max_value_vertical * 1.1, 0)
imshow_args = dict(vmin=0, vmax=1, cmap='gray')
plt.subplot(ax_all)
plt.title('All channels')
plt.imshow(self.img, **imshow_args)
plt.subplot(ax_red_img)
plt.title('Red')
plt.imshow(self.red, **imshow_args)
plt.subplot(ax_green_img)
plt.title('Green')
plt.imshow(self.green, **imshow_args)
plt.subplot(ax_blue_img)
plt.title('Blue')
plt.imshow(self.blue, **imshow_args)
plt.show()
I'm using matplotlib 3.1.1 and python 3.7.1.