简体   繁体   中英

how to plot geotiff data in specific area (lat/lon) with python

I have a geotiff raster data sets with elevation data init and i want to plot it in specific area, such as 60°E - 70° E ,70°S - 80°E.

I have a bit of code from here ,but the pcolormesh seem couldn't plot my geotif.it's all red. picture . The picture is shown by imshow as really picture

When I try to make a plot with this code below:

path = "F:\\Mosaic_h1112v28_ps.tif"
dataset = gdal.Open(path)
data = dataset.ReadAsArray()
x0, dx, dxdy, y0, dydx, dy = dataset.GetGeoTransform()
nrows, ncols = data.shape
londata = np.linspace(x0, x0+dx*ncols)
latdata = np.linspace(y0, y0+dy*nrows)
lons, lats = np.meshgrid(lonarray, latarray)  
fig = plt.figure(figsize=(8, 8))
m = Basemap(projection='lcc', lon_0=67.5, lat_0=-68.5, height=950000,
            width=580000, resolution='h') 
m.drawcoastlines() 
x, y = m(lons, lats) 

Then i dont know how to continue it . I just want to use imshow , but the imshow dont specify area(lat/lon).

I will really appreciate your help.

Here is my solution.

1. Import GEOTIF file and transform it into 2-D array data

from osgeo import gdal
pathToRaster = r'./xxxx.tif'
raster = gdal.Open(pathToRaster,  gdal.GA_ReadOnly)
data = raster.GetRasterBand(1).ReadAsArray()
data = data[::-1]  

2. Plot it using Pcolormesh

kk = plt.pcolormesh(data,cmap = plt.cm.Reds,alpha = 0.45, zorder =2)

It's a good question, here is my solution.

Required packages: georaster with its dependencies (gdal, etc).
Data for demo purposes downloadable from http://dwtkns.com/srtm/

import georaster
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

fig = plt.figure(figsize=(8,8))

# full path to the geotiff file
fpath = r"C:\\path_to_your\geotiff_file\srtm_57_10.tif"  # Thailand east

# read extent of image without loading
# good for values in degrees lat/long
# geotiff may use other coordinates and projection
my_image = georaster.SingleBandRaster(fpath, load_data=False)

# grab limits of image's extent
minx, maxx, miny, maxy = my_image.extent

# set Basemap with slightly larger extents
# set resolution at intermediate level "i"
m = Basemap( projection='cyl', \
            llcrnrlon=minx-2, \
            llcrnrlat=miny-2, \
            urcrnrlon=maxx+2, \
            urcrnrlat=maxy+2, \
            resolution='i')

m.drawcoastlines(color="gray")
m.fillcontinents(color='beige')

# load the geotiff image, assign it a variable
image = georaster.SingleBandRaster( fpath, \
                        load_data=(minx, maxx, miny, maxy), \
                        latlon=True)

# plot the image on matplotlib active axes
# set zorder to put the image on top of coastlines and continent areas
# set alpha to let the hidden graphics show through
plt.imshow(image.r, extent=(minx, maxx, miny, maxy), zorder=10, alpha=0.6)

plt.show()

The resulting plot:

在此处输入图片说明

Edit1

My original answer places focus on how to plot simple geotiff image on the most basic projection with Basemap. A better answer was not possible without access to all required resources (ie geotiff file).

Here I try to improve my answer.

I have clipped a small portion from whole world geotiff file. Then reproject (warp) it to LCC projection specifications defined by Basemap() to be used. All the process were done with GDAL softwares. The resulting file is named "lcc_2.tiff". With this geotiff file, the plotting of the image is done with the code below.

The most important part is that geotiff file must have the same coordinate system (same projection) as the projection used by Basemap.

import georaster
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

fig = plt.figure(figsize=(8,8))

m = Basemap(projection='lcc', lon_0=67.5, lat_0=-68.5, \
            height=950000, width=580000, resolution='h')

m.drawcoastlines()
m.fillcontinents(color='beige')

image = georaster.SingleBandRaster( "lcc_2.tiff", latlon=False)
plt.imshow(image.r, extent=image.extent, zorder=10, alpha=0.6)

plt.show()

The output map:

在此处输入图片说明

You can use rioxarray

import rioxarray as rio
ds = rio.open_rasterio(path)
# Example lat lon range for subset
geometries = [
{
    'type': 'Polygon',
    'coordinates': [[
        [33.97301017665958, -118.45830810580743],
        [33.96660083660732, -118.37455741054782],
        [33.92304171545437, -118.37151348516299],
        [33.915042933806724, -118.42909440702563]
    ]]
}
]
clipped = ds.rio.clip(geometries)
clipped.plot()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM