cartopy icon indicating copy to clipboard operation
cartopy copied to clipboard

Issue plotting WRF Data with Lambert Projection

Open ADgit7 opened this issue 2 years ago • 5 comments

Hello,

I recently started using python via jupyter on windows to plot netCDF data. However I am having issues plotting data I got from a WRF run that uses lambert projection. I cannot seem to get the coastlines to be overlayed and lined up with the data plot i.e. the coastlines overylay either does not show up at all or is slightly offset from the data. Below is the codes I have tried to use but which resulted in separate issues. Any assistance in resolving this errors would be appreciated.

#Code 1:

from netCDF4 import Dataset import xarray as xr import matplotlib.pyplot as plt import cartopy.crs as ccrs

ds = xr.open_dataset("datafolder\output.nc") temp2 = ds.T2[0,:,:] temp2

fig=plt.figure(figsize=(5, 5)) ax2 = fig.add_subplot(1, 1, 1, projection=ccrs.LambertConformal())

temp2.plot(ax=ax2, cmap='jet', transform=ccrs.LambertConformal())

ax1.add_feature(cfeature.BORDERS, edgecolor='black') ax1.add_feature(cfeature.COASTLINE, edgecolor='black')

plt.show() #-------------------------------------------------------------------------#

#Code 2: from netCDF4 import Dataset import xarray as xr import matplotlib.pyplot as plt import cartopy.crs as ccrs

ds = xr.open_dataset(r"datafolder\output.nc") temp2 = ds.T2[0,:,:] temp2

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

ax1 = fig.add_subplot(1, 1, 1, extent=(-140, -73, 14, 60), projection=ccrs.LambertConformal())

temp2.plot(ax=ax1, cmap='jet', transform=ccrs.LambertConformal())

ax1.add_feature(cfeature.BORDERS, edgecolor='black') ax1.add_feature(cfeature.COASTLINE, edgecolor='black')

plt.show() #----------------------------------------------------------------#

Attached are the output of code 1 and code 2 respectively Code 2 result Code 1 result

ADgit7 avatar Oct 02 '23 23:10 ADgit7

You haven't set the extent, so it is likely that the image one has a different set of limits than the top one. Try using set_extent() or set_xlim().

For the boundaries you're looking for you likely just need to adjust the zorder of the artists so you place them in the order you want. There is also an ax.coastlines() method that should put the coast higher so that it shows as well.

greglucas avatar Oct 03 '23 01:10 greglucas

You haven't set the extent, so it is likely that the image one has a different set of limits than the top one. Try using set_extent() or set_xlim().

For the boundaries you're looking for you likely just need to adjust the zorder of the artists so you place them in the order you want. There is also an ax.coastlines() method that should put the coast higher so that it shows as well.

Hi,

Thank you for your suggestions. However I am still running into similar issues. I have tried to use set_xlim() and placing ax.coastlines() above the line which plots the temperature. I tried the below code but it does not seem to work either. Are there any suggestions to improve it?

Code 3:

from netCDF4 import Dataset import xarray as xr import matplotlib.pyplot as plt import cartopy.crs as ccrs

ds = xr.open_dataset("datafolder\output.nc") temp2 = ds.T2[0,:,:] temp2

fig = plt.figure(figsize=(5, 5)) ax1 = plt.axes(projection=ccrs.LambertConformal()) ax1.coastlines()

temp2.plot(ax=ax1, cmap='jet', xlim=(-0.5, 413.5), ylim=(-0.5, 323.5), transform=ccrs.LambertConformal())

ax1.set_extent([-140, -75, 17, 45], crs=ccrs.PlateCarree())

ax1.coastlines()

plt.show()

#------------------------------------------------------------#

Running the above results in only the coastlines being drawn with no data plotted similar to image 1 in the original post.

While removing the 'ax1.set_extent([-140, -75, 17, 45], crs=ccrs.PlateCarree())' line resulted in no coastlines being drawn but the data being plotted like in image 2 of the original post, I also notice placing that line above the temp2.plot line also does something similar to that. It's like the coastline overlay is not transparent.

The data to be plotted is in Lambert conformal projection, is that the correct way to plot it in Plate Carree? I have tried plotting other datasets that came in other projections and did not have these issues.

I am quite new to this so apologies if these questions are silly.

ADgit7 avatar Oct 03 '23 16:10 ADgit7

I think if you put xlim/ylim in the call to temp2, you are specifying xlim/ylim in LambertConformal units because you are specifying that transform. But, I'm guessing those units are really lat/lon, so you might be able to just remove those and get the plot you want? As long as your data is in LCC units and your xarray dataset has the coordinates set up properly.

from netCDF4 import Dataset
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs

ds = xr.open_dataset("datafolder\output.nc")
temp2 = ds.T2[0,:,:]
temp2

fig = plt.figure(figsize=(5, 5))
ax1 = plt.axes(projection=ccrs.LambertConformal())
ax1.coastlines()

temp2.plot(ax=ax1, cmap='jet', transform=ccrs.LambertConformal())

ax1.set_extent([-140, -75, 17, 45], crs=ccrs.PlateCarree())

ax1.coastlines()

plt.show()

wrf-python might also be able to help you? It looks like they have routines for handling WRF output already: https://wrf-python.readthedocs.io/en/latest/plot.html

greglucas avatar Oct 03 '23 22:10 greglucas

I think if you put xlim/ylim in the call to temp2, you are specifying xlim/ylim in LambertConformal units because you are specifying that transform. But, I'm guessing those units are really lat/lon, so you might be able to just remove those and get the plot you want? As long as your data is in LCC units and your xarray dataset has the coordinates set up properly.

from netCDF4 import Dataset
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs

ds = xr.open_dataset("datafolder\output.nc")
temp2 = ds.T2[0,:,:]
temp2

fig = plt.figure(figsize=(5, 5))
ax1 = plt.axes(projection=ccrs.LambertConformal())
ax1.coastlines()

temp2.plot(ax=ax1, cmap='jet', transform=ccrs.LambertConformal())

ax1.set_extent([-140, -75, 17, 45], crs=ccrs.PlateCarree())

ax1.coastlines()

plt.show()

wrf-python might also be able to help you? It looks like they have routines for handling WRF output already: https://wrf-python.readthedocs.io/en/latest/plot.html

Thanks for the link, hopefully it will help as I continue to work towards a solution. Here is the link to the WRF output nc file i was using in case anyone is interested in replicating it. https://drive.google.com/file/d/1s-0RLcaqIG0OoFEZtsE6_1xsE9B0DM1_/view?usp=sharing

ADgit7 avatar Oct 04 '23 16:10 ADgit7

Hello,

I recently started using python via jupyter on windows to plot netCDF data. However I am having issues plotting data I got from a WRF run that uses lambert projection. I cannot seem to get the coastlines to be overlayed and lined up with the data plot i.e. the coastlines overylay either does not show up at all or is slightly offset from the data. Below is the codes I have tried to use but which resulted in separate issues. Any assistance in resolving this errors would be appreciated.

#Code 1:

from netCDF4 import Dataset import xarray as xr import matplotlib.pyplot as plt import cartopy.crs as ccrs

ds = xr.open_dataset("datafolder\output.nc") temp2 = ds.T2[0,:,:] temp2

fig=plt.figure(figsize=(5, 5)) ax2 = fig.add_subplot(1, 1, 1, projection=ccrs.LambertConformal())

temp2.plot(ax=ax2, cmap='jet', transform=ccrs.LambertConformal())

ax1.add_feature(cfeature.BORDERS, edgecolor='black') ax1.add_feature(cfeature.COASTLINE, edgecolor='black')

plt.show() #-------------------------------------------------------------------------#

#Code 2: from netCDF4 import Dataset import xarray as xr import matplotlib.pyplot as plt import cartopy.crs as ccrs

ds = xr.open_dataset(r"datafolder\output.nc") temp2 = ds.T2[0,:,:] temp2

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

ax1 = fig.add_subplot(1, 1, 1, extent=(-140, -73, 14, 60), projection=ccrs.LambertConformal())

temp2.plot(ax=ax1, cmap='jet', transform=ccrs.LambertConformal())

ax1.add_feature(cfeature.BORDERS, edgecolor='black') ax1.add_feature(cfeature.COASTLINE, edgecolor='black')

plt.show() #----------------------------------------------------------------#

Attached are the output of code 1 and code 2 respectively Code 2 result Code 1 result

The problem appears to be how xarray interacts and interprets the variables in the specific WRF-DART output file I was using as input. So instead of using xarray to grab read variable data to plot directly, the variables were converted to numpy arrays first:

import xarray as xr import matplotlib.pyplot as plt import cartopy.crs as ccrs

with xr.open_dataset("output_mean.nc") as ds: ds = ds.isel(Time=0) # using the first timestep lons = ds["XLONG"].to_numpy() lats = ds["XLAT"].to_numpy() data = ds["T2"].to_numpy()

#the above converts the specified variables to numpy arrays.

map_proj = ccrs.LambertConformal( central_latitude=39, central_longitude=-101, standard_parallels=(32, 46), )

fig, ax = plt.subplots( figsize=(8, 5), facecolor="w", subplot_kw=dict(projection=map_proj ), )

cm = ax.pcolormesh(lons, lats, data, cmap='turbo', transform=ccrs.PlateCarree()) cb = fig.colorbar(cm, ax=ax, shrink=.5)

ax.coastlines()

#------------------------------------

The above code help solve the issue I was having and allowed the data plot and the coastline overlay to be matched up perfectly.

ADgit7 avatar Oct 06 '23 23:10 ADgit7