thiirane
thiirane

Reputation: 45

nonlinear scaling image in figure axis matplotlib

enter image description hereI hope I have not over-looked as previously asked question. I don't think so. I have an image of a spectrum. I have several laser lines for calibration. Since the laser lines and the spectrum were collected in the same way they should be correlated in pixel distance. The relationship between pixel number and wavelength is nonlinear. I have fit the pixel number along the x-axis against the wavelength of the laser lines (blue @ 405nm green @ 532nm and red @ 650nm) using a 3rd degree polynomial with high correlation. I want to plot the spectrum by computing the wavelength( nm) directly from the pixel number and display the wavelength beneath the spectrum. Is this possible without overlapping the image on another figure? spectrograph of Laser Lines

import matplotlib.pyplot as plt
from scipy import ndimage
from pylab import *
import numpy as np

import skimage

image= laser_lines

print(image.shape)


for i in range(image.shape[1]):
    x=i^3*-3.119E-6+2.926E-3*i^2+0.173*i+269.593
for j in range(image.shape[0]):
    y=image[i,j]
imshow(image)    


plt.show()

Upvotes: 0

Views: 1071

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339310

Probably the easiest option is to use a pcolormesh instead of an imshow plot. The pcolormesh shows the edges of a grid, such that you might simply transform the original grid using the functional dependence between pixels and wavelength to define the edges of each pixel in terms of wavelength.

import numpy as np 
import matplotlib.pyplot as plt

image = np.sort(np.random.randint(0,256,size=(400,600)),axis=0)


f = lambda i: i**3*-3.119E-6+2.926E-3*i**2+0.173*i+269.593
xi = np.arange(0,image.shape[1]+1)-0.5
yi = np.arange(0,image.shape[0]+1)-0.5
Xi, Yi = np.meshgrid(xi, yi)

Xw = f(Xi)

fig, (ax) = plt.subplots(figsize=(8,4))

ax.pcolormesh(Xw, Yi, image)

ax.set_xlabel("wavelength [nm]")
plt.show()

enter image description here

If the image has 3 colorchannels, you need to use the color argument of pcolormesh to set the color of each pixel, as shown in this question: Plotting an irregularly-spaced RGB image in Python

import numpy as np 
import matplotlib.pyplot as plt

r = np.sort(np.random.randint(0,256,size=(200,600)),axis=1)
g = np.sort(np.random.randint(0,256,size=(200,600)),axis=0)
b = np.sort(np.random.randint(0,256,size=(200,600)),axis=1)
image = np.dstack([r, g, b])

color = image.reshape((image.shape[0]*image.shape[1],image.shape[2]))
if color.max() > 1.:
    color = color/255.

f = lambda i: i**3*-3.119E-6+2.926E-3*i**2+0.173*i+269.593
xi = np.arange(0,image.shape[1]+1)-0.5
yi = np.arange(0,image.shape[0]+1)-0.5
Xi, Yi = np.meshgrid(xi, yi)

Xw = f(Xi)

fig, (ax) = plt.subplots(figsize=(8,4))

pc = ax.pcolormesh(Xw, Yi, Xw, color=color )
pc.set_array(None)
ax.set_xlabel("wavelength [nm]")
plt.show()

Upvotes: 1

Related Questions