3

Question : Is there a way to resample gridded values from a geodataframe to plot a smoother map?

Details : I am working with a 24x24 grid named gdf. Each cell of the grid has a value and an id as attributes:

#gdf.head()

    id      values      geometry
0   1       52.390119   POLYGON ((653179.710 6859158.392, 653179.710 6...
1   2       52.390119   POLYGON ((653179.710 6858908.392, 653179.710 6...
2   3       52.390119   POLYGON ((653179.710 6858658.392, 653179.710 6...
3   4       49.592331   POLYGON ((653179.710 6858408.392, 653429.710 6...
4   5       52.390119   POLYGON ((653429.710 6858408.392, 653179.710 6...

This is the type of map I get when I plot it:

Initial gridded data

As you can see there are very harsh changes in the values from a cell to another in the plot and I would like to smoother that out.

Is there a way to divide each cells into 2 or 3 sub-cells (horizontally and vertically) to get a grid of higher resolution and then interpolate the values to get smooth gradients instead of this? Knowing that I am trying to keep the data as a geodataframe since I need to convert them into a shapefile later on.


I found a method that allows me to do it via plt.imshow() as there is an interpolation option ; which would give me exactly what I want but this only gives an image as an output, I cannot directly modify gdf with it:

grid = np.array(file.data).reshape(-1, 24)[::-1]

fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(20, 20), subplot_kw={'xticks': [], 'yticks': []})

for ax, interp_method in zip(axs.flat, methods):
    ax.imshow(grid, interpolation='lanczos', cmap='RdYlGn_r')

plt.tight_layout()
plt.show()
I.M.
  • 344
  • 3
  • 14
  • Possibly a duplicate of https://stackoverflow.com/questions/37872171/how-can-i-perform-two-dimensional-interpolation-using-scipy – Victor Deleau Jan 30 '20 at 19:05
  • Isn't it different? They consider scattered points for the interpolation in that post whereas I have gridded data with no missing values in between. – I.M. Jan 30 '20 at 23:23
  • Take it this way. You can represent your gridded values as an array. You can "inflate" your array up to given ratio to have missing values (your known values are now scattered) that you would then try to impute using the answer of this post – Victor Deleau Jan 30 '20 at 23:35
  • 1
    I see, I will try that out. Wouldn't I lose informations if I turn a geodataframe into an array (especially the ```geometry``` information)? I'm not used to using them so I am a bit unsure. – I.M. Jan 31 '20 at 10:12
  • Does `geometry` represents a cell's polygon ? If yes, because you have a square grid, it's pretty much redundant information, as you can recompute those values using just the min/max coordinate of your map. So using your interpolated 2D array of float you can create a new geodataframe with the `polygons` column as well – Victor Deleau Jan 31 '20 at 15:17

1 Answers1

1

To complement my comment, another way is simply to consider your grid as an image and use the PIL library:

import numpy as np
from PIL import Image

image = PIL.Image.from_array(grid)
w, h = image.size
ratio = 4
image = image.resize((w*ratio, h*ratio), Image.BILINEAR)
image.show()
grid = np.array(image)

You can use different interpolation methods as well. To get your data back into a pandas dataframe:

# flatten your grid and get your values back into a column
pd.DataFrame(grid.flatten(), columns=['values'])

# add an id column that starts a 1
df['id'] = df.index + 1
Victor Deleau
  • 875
  • 5
  • 17
  • Thank you for your answer. Is there a way to convert the ```grid``` array back into a DataFrame (or GeoDataFrame) while keeping the right order of cells so I can plot the output ? – I.M. Jan 31 '20 at 10:37
  • 1
    Thank you very much for your help! I managed to get the desired result! – I.M. Jan 31 '20 at 16:08