Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue plotting WRF Data with Lambert Projection #2256

Open
ADgit7 opened this issue Oct 2, 2023 · 5 comments
Open

Issue plotting WRF Data with Lambert Projection #2256

ADgit7 opened this issue Oct 2, 2023 · 5 comments

Comments

@ADgit7
Copy link

ADgit7 commented Oct 2, 2023

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

@greglucas
Copy link
Contributor

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.

@ADgit7
Copy link
Author

ADgit7 commented Oct 3, 2023

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.

@greglucas
Copy link
Contributor

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

@ADgit7
Copy link
Author

ADgit7 commented Oct 4, 2023

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
Copy link
Author

ADgit7 commented Oct 6, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants