Creating custom axes in matplotlib without affecting displayed image

Viewed 196

How do I create custom axes on a matplotlib plot without affecting the displayed data?

I want to plot some data with an image (from which the data is) below the plot itself with the same axes as the data plot.

For the plotted data I've adjusted the x-axes by using np.linespace() but I cannot do that for an image.

Below are an exemplary picture and code example of what I was able to create myself. What I try to do is that the x-axes of the image subplot shows the same ticks and labels as the data subplot. This should not change the appearance of the display data or image itself only the axes ticks/labels.

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

#create figure
fig, axs=plt.subplots(nrows=2, ncols=1, figsize=(6, 4), dpi=300)

#plot example function in subplot 0
time = np.linspace(0, 10, 100)
axs[0].plot(time, np.sin(time))
axs[0].set_xlim(0-2, 10+2)

#load image
img = cv.imread(r"lena.png")
#convert BGR to RGB
RGB_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

#show image in subplot 1
axs[1].imshow(RGB_img)
axs[1].set_xlim(0-2, img.shape[1]+2)
axs[1].get_yaxis().set_visible(False)
1 Answers

Edit: Incorporated OP's suggestions to automate the process.

You can set arbitrary tick marks and labels with ax.set_xticks() and ax.set_xticklabels(). Combining this with ax.get_xticks(), it is possible to compute the image ticks from the original ticks:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

#create figure
fig, axs=plt.subplots(nrows=2, ncols=1, figsize=(6, 4), dpi=300)

#plot example function in subplot 0
time = np.linspace(0, 10, 100)
axs[0].plot(time, np.sin(time))
axs[0].set_xlim(0-2, 10+2)

#load image
img = mpimg.imread(r"lena.png")

#show image in subplot 1
axs[1].imshow(img)
axs[1].set_xlim(0-2, img.shape[1]+2)
axs[1].get_yaxis().set_visible(False)

# convert the ticks from the data to the pixel values
ticks_new = axs[0].get_xticks() * (img.shape[1] / 10)
axs[1].set_xticks(ticks_new)

# set labels
tick_labels = [int(round(x)) for x in axs[0].get_xticks()]
axs[1].set_xticklabels(tick_labels);

sample plot

Related