Skip to content Skip to sidebar Skip to footer

Contour Plot Data (lat,lon,value) Within Boundaries And Export Geojson

I'm trying to interpolate data within boundaries and plot contour lines (polygons) based on Latitude, longitude, value data from csv files. Results I want print as geojson. I'm stu

Solution 1:

I guess there is some mistake in your code (according to your data you shouldn't do x = data[:1] but more x = data[..., 1]).

With your of data, the basic steps I will follow to interpolate the z value and fetch an output as a geojson would require at least the shapely module (and here geopandas is used for the convenience).

import numpy as np
import matplotlib.pyplot as plt
from geopandas import GeoDataFrame
from matplotlib.mlab import griddata
from shapely.geometry import Polygon, MultiPolygon

defcollec_to_gdf(collec_poly):
    """Transform a `matplotlib.contour.QuadContourSet` to a GeoDataFrame"""
    polygons, colors = [], []
    for i, polygon inenumerate(collec_poly.collections):
        mpoly = []
        for path in polygon.get_paths():
            try:
                path.should_simplify = False
                poly = path.to_polygons()
                # Each polygon should contain an exterior ring + maybe hole(s):
                exterior, holes = [], []
                iflen(poly) > 0andlen(poly[0]) > 3:
                    # The first of the list is the exterior ring :
                    exterior = poly[0]
                    # Other(s) are hole(s):iflen(poly) > 1:
                        holes = [h for h in poly[1:] iflen(h) > 3]
                mpoly.append(Polygon(exterior, holes))
            except:
                print('Warning: Geometry error when making polygon #{}'
                      .format(i))
        iflen(mpoly) > 1:
            mpoly = MultiPolygon(mpoly)
            polygons.append(mpoly)
            colors.append(polygon.get_facecolor().tolist()[0])
        eliflen(mpoly) == 1:
            polygons.append(mpoly[0])
            colors.append(polygon.get_facecolor().tolist()[0])
    return GeoDataFrame(
        geometry=polygons,
        data={'RGBA': colors},
        crs={'init': 'epsg:4326'})


data = np.genfromtxt('temp.csv', delimiter=',')
x = data[..., 1]
y = data[..., 2]
z = data[..., 3]
xi = np.linspace(x.min(), x.max(), 200)
yi = np.linspace(y.min(), y.max(), 200)
zi = griddata(x, y, z, xi, yi, interp='linear') # You could also take a look to scipy.interpolate.griddata

nb_class = 15# Set the number of class for contour creation# The class can also be defined by their limits like [0, 122, 333]
collec_poly = plt.contourf(
    xi, yi, zi, nb_class, vmax=abs(zi).max(), vmin=-abs(zi).max())

gdf = collec_to_gdf(collec_poly)
gdf.to_json()
# Output your collection of features as a GeoJSON:# '{"type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[51.563214073747474,# (...)

Edit: You can grab the colors values (as an array of 4 values in range 0-1, representing RGBA values) used by matplotplib by fetching them on each item of the collection with the get_facecolor() method (and then use them to populate one (or 4) column of your GeoDataFrame :

colors = [p.get_facecolor().tolist()[0] forpin collec_poly.collections]
gdf['RGBA'] = colors

Once you have you GeoDataFrame you can easily get it intersected with your boundaries. Use these boundaries to make a Polygon with shapely and compute the intersection with your result:

mask = Polygon([(51,17), (51,18), (52,18), (52,17), (51,17)])
gdf.geometry = gdf.geometry.intersection(mask)

Or read your geojson as a GeoDataFrame:

from shapely.ops import unary_union, polygonize
boundary = GeoDataFrame.from_file('your_geojson')
# Assuming you have a boundary as linestring, transform it to a Polygon:
mask_geom = unary_union([i for i in polygonize(boundary.geometry)])
# Then compute the intersection:
gdf.geometry = gdf.geometry.intersection(mask_geom)

Solution 2:

Almost I got what I excepted. Based on mgc answer. I change griddata as you suggest to scipy.interpolate.griddata and interpolation method to nearest. Now its works like I want.

Only last thing that I need is to limit this interpolation to polygon (boundaries) also from geoJson.

The other problem is to export to geojson polygons WITH colors as attributes.

import numpy as np
import matplotlib.pyplot as plt
#from matplotlib.mlab import griddatafrom scipy.interpolate import griddata

from geopandas import GeoDataFrame
from shapely.geometry import Polygon, MultiPolygon

defcollec_to_gdf(collec_poly):
    """Transform a `matplotlib.contour.QuadContourSet` to a GeoDataFrame"""
    polygons = []
    for i, polygon inenumerate(collec_poly.collections):
        mpoly = []
        for path in polygon.get_paths():
            try:
                path.should_simplify = False
                poly = path.to_polygons()
                # Each polygon should contain an exterior ring + maybe hole(s):
                exterior, holes = [], []
                iflen(poly) > 0andlen(poly[0]) > 3:
                    # The first of the list is the exterior ring :
                    exterior = poly[0]
                    # Other(s) are hole(s):iflen(poly) > 1:
                        holes = [h for h in poly[1:] iflen(h) > 3]
                mpoly.append(Polygon(exterior, holes))
            except:
                print('Warning: Geometry error when making polygon #{}'
                      .format(i))
        iflen(mpoly) > 1:
            mpoly = MultiPolygon(mpoly)
            polygons.append(mpoly)
        eliflen(mpoly) == 1:
            polygons.append(mpoly[0])
    return GeoDataFrame(geometry=polygons, crs={'init': 'epsg:4326'})

data = np.genfromtxt('temp2.csv', delimiter=',')
x = data[..., 1]
y = data[..., 2]
z = data[..., 4]
xi = np.linspace(x.min(), x.max(), num=100)
yi = np.linspace(y.min(), y.max(), num=100)

#zi = griddata(x, y, z, xi, yi, interp='nn') # You could also take a look to scipy.interpolate.griddata
zi = griddata((x, y), z, (xi[None,:], yi[:,None]), method='nearest')

nb_class = [5,10,15,20,25,30,35,40,45,50] # Set the number of class for contour creation# The class can also be defined by their limits like [0, 122, 333]
collec_poly = plt.contourf(
    xi, yi, zi, nb_class, vmax=abs(zi).max(), vmin=-abs(zi).max())

gdf = collec_to_gdf(collec_poly)
#gdf.to_json()print gdf.to_json()

plt.plot(x,y)

plt.show()

Post a Comment for "Contour Plot Data (lat,lon,value) Within Boundaries And Export Geojson"