Python – Remeshes 2D data to a larger 2D mesh at a given coordinate in Python

Remeshes 2D data to a larger 2D mesh at a given coordinate in Python… here is a solution to the problem.

Remeshes 2D data to a larger 2D mesh at a given coordinate in Python

I have a square two-dimensional array

data, and I want to add it to a larger two-dimensional array frame, in a given set of non-integer coordinates coords. The idea is that data will be interpolated onto the frame, with its center at the new coordinates.

Some toy data:

# A gaussian to add to the frame
x, y = np.meshgrid(np.linspace(-1,1,10), np.linspace(-1,1,10))
data = 50*np.exp(-np.sqrt(x**2+y**2)**2)

# The frame to add the gaussian to
frame = np.random.normal(size=(100,50))

# The desired (x,y) location of the gaussian center on the new frame
coords = 23.4, 22.6

It’s an idea. I would like to add this :

gaussian

To this end:

enter image description here

Get this:

enter image description here

If the coordinates are integers (indexes), I can of course simply add them like this :

frame[23:33,22:32] += data

But I would like to be able to specify non-integer coordinates so that data is remeshed and added to the frame.

I have studied PIL. Image method, but my use case only applies to 2D data, not images. Is there a way to do this with just scipy? Can this be done with interp2d or something similar? Any guidance would be appreciated!

Solution

Scipy’s The function in shift scipy.ndimage.interpolation is what you’re looking for, as long as the grid spacing between data and frame overlaps. If not, check out the other answers. The shift function can take float as input and spline interpolate. First, I put the data into an array as large as a frame, then shift, then add. Make sure to reverse the coordinate list because x is the rightmost dimension in the numpy array. A nice feature of shift is that it sets those values that are out of range to zero.

import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage.interpolation import shift

# A gaussian to add to the frame.
x, y = np.meshgrid(np.linspace(-1,1,10), np.linspace(-1,1,10))
data = 50*np.exp(-np.sqrt(x**2+y**2)**2)

# The frame to add the gaussian to
frame = np.random.normal(size=(100,50))
x_frame = np.arange(50)
y_frame = np.arange(100)

# The desired (x,y) location of the gaussian center on the new frame.
coords = np.array([23.4, 22.6])

# First, create a frame as large as the frame.
data_large = np.zeros(frame.shape)
data_large[:data.shape[0], :data.shape[1]] = data[:,:]

# Subtract half the distance as the bottom left is at 0,0 instead of the center.
# The shift of 4.5 is because data is 10 points wide.
# Reverse the coords array as x is the last coordinate.
coords_shift = -4.5
data_large = shift(data_large, coords[::-1] + coords_shift)

frame += data_large

# Plot the result and add lines to indicate to coordinates
plt.figure()
plt.pcolormesh(x_frame, y_frame, frame, cmap=plt.cm.jet)
plt.axhline(coords[1], color='w')
plt.axvline(coords[0], color='w')
plt.colorbar()
plt.gca().invert_yaxis()
plt.show()

The script gives you the following image with the desired coordinates indicated by a white dashed line.

Interpolated result

Related Problems and Solutions