Search code examples
python2dinterpolationsmoothing

Smooth 2D interpolation map using Z values (1 column) at known X and Y coordinates (1 column each)


Pardon my ignorance but somehow all interpolation, smoothing of 2D maps solutions require a relationship Z~f(x,y) and does not fit my problem. This is closest to my problem : smoothing surface plot from matrix

I have three columns of same lengths: X coordinates, Y coordinates, and the Z-value

I can plot a scatterplot like this

scatterplot

with Z as the filler / colormap, but it looks like points on a grid with regular intervals.

I want to interpolate and smooth them to fill in the gaps between the gridpoints but I don't know what the Z~f(x,y) is. Is there a way to achieve this?

UPDATE credit to @Wombatz for the interpolation (see solution below). I have added his contribution to my code and figured out how to resample 1D-array Z-col to a 2D-array that fits my (x,y) array. My code below:

import matplotlib.pyplot as plt
from matplotlib.pyplot import imshow
from scipy.interpolate import griddata
import numpy as np

x = [0,0,1,1,2,2] #1D
y = [0,1,0,1,0,1] #1D
Z = [1,2,3,4,5,6] #1D

extent = (min(x), max(x), min(y), max(y))
xs,ys = np.mgrid[extent[0]:extent[1]:3j, extent[2]:extent[3]:2j] #2D x,y
Z_resampled = griddata((x, y), Z, (xs, ys)) #2D z


imshow(z_resampled, interpolation="gaussian", extent=extent, origin="lower")

Scatterplot of x,y,z: scatter

My code gives me this: smoothed


Solution

  • I assume you have the following data:

    • x: the x values [-120, -100, ..., 140, 160]
    • y: the y values [-180, -160, ..., 80, 100]
    • z: a 2d array containing the z values for each point in the grid

    Now you can plot the data as an image which does the interpolation for you:

    from matplotlib.pyplot import imshow
    
    extent = [x.min(), x.max(), y.min(), y.max()]
    imshow(z, interpolation="none", extent=extent, origin="lower")
    

    scatter plot as image

    The extent defines the axes for the image. You can play around with the interpolation parameter.

    The black circles are the markers from the scatter plot (not shown in the code).

    If you need the scatter plot markers to be in the center of each pixel, you must change the extent like this:

    ox = (x.max() - x.min()) / (x.size * 2)
    oy = (y.max() - y.min()) / (y.size * 2)
    extent = [x.min() - ox, x.max() + ox, y.min() - oy, y.max() + oy]
    

    Together with bilinear interpolation this looks as follows:

    enter image description here