Unidata / MetPy

MetPy is a collection of tools in Python for reading, visualizing and performing calculations with weather data.
https://unidata.github.io/MetPy/
BSD 3-Clause "New" or "Revised" License
1.26k stars 415 forks source link

WPC Surface Bulletins for the southern hemisphere are not being parsed correctly #3535

Closed diegormsouza closed 3 months ago

diegormsouza commented 4 months ago

What went wrong?

Hi,

Since MetPy 1.6, plotting fronts is very easy: https://unidata.github.io/MetPy/latest/examples/plots/Plotting_Surface_Analysis.html https://www.unidata.ucar.edu/blogs/developer/entry/metpy-mondays-287-parsing-weather

And parsing the WPC surface bulletins is also easy, with the parse_wpc_surface_bulletin call.

When this new version was released, I was curious to know if WPC produced these bulletins for Latin America and they were not.

So I contacted them and asked if they could produce these bulletins for LatAm and thankfully, they are working on it!

They have already shared some samples, but unfortunatelly, the results are not as expected (image below).

I have also attached a couple of samples provided by WPC: WPC_bulletins_samples_LatAm.zip

Do you have any hints? It looks like it is not taking into account the leading "-" for each coded lat/lon in the Southern Hemisphere. It takes the first 3 characters as the latitude and the last 4 as the longitude. So in the northern hemisphere, the code 6251365 is 62.5 latitude and -136.5 Longitude. In the southern hemisphere, the "-" sign is added. The code -3880854 should be -38.8 latitude and -85.4 longitude. From the map below, the code appears to be reading in the first 3 characters of the code (-38) to get a -3.8 latitude. The longitudes appear to be fine so it looks like the code is taking the last 4 characters correctly.

Thanks!

# Set up a default figure and map
fig = plt.figure(figsize=(15, 10), dpi=150)
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())

# define the region
min_lon = -130
max_lon = -20
min_lat = -60
max_lat = 30
ax.set_extent([min_lon , max_lon, min_lat, max_lat], crs=ccrs.PlateCarree())

# add some features
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.BORDERS)
ax.add_feature(cfeature.STATES)
ax.add_feature(cfeature.LAKES)

# add gridlines
gl = ax.gridlines(crs=ccrs.PlateCarree(), color='white', alpha=1.0, linestyle='--', linewidth=0.5,
xlocs=np.arange(-180, 181, 10), ylocs=np.arange(-90, 91, 10), draw_labels=True)
gl.top_labels = False; gl.right_labels = False
gl.xpadding = -5; gl.ypadding = -5
gl.ylabel_style = {'color': 'white', 'size': 6, 'weight': 'bold'}
gl.xlabel_style = {'color': 'white', 'size': 6, 'weight': 'bold'}

# Parse the bulletin and plot it
df = parse_wpc_surface_bulletin('/content/20240207Test_coded_bulletin_SAMd3_hires.dat')
plot_bulletin(ax, df)

ax.set_title(f'WPC Surface Analysis Valid {df.valid.dt.strftime("%HZ %d %b %Y")[0]}')
add_metpy_logo(fig, 50, 50, size='small')
plt.show()

image

Operating System

Linux

Version

1.6

Python Version

3.10

Code to Reproduce

# Set up a default figure and map
fig = plt.figure(figsize=(15, 10), dpi=150)
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())

# define the region
min_lon = -130
max_lon = -20
min_lat = -60
max_lat = 30
ax.set_extent([min_lon , max_lon, min_lat, max_lat], crs=ccrs.PlateCarree())

# add some features
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.LAND)
ax.add_feature(cfeature.BORDERS)
ax.add_feature(cfeature.STATES)
ax.add_feature(cfeature.LAKES)

# add gridlines
gl = ax.gridlines(crs=ccrs.PlateCarree(), color='white', alpha=1.0, linestyle='--', linewidth=0.5,
xlocs=np.arange(-180, 181, 10), ylocs=np.arange(-90, 91, 10), draw_labels=True)
gl.top_labels = False; gl.right_labels = False
gl.xpadding = -5; gl.ypadding = -5
gl.ylabel_style = {'color': 'white', 'size': 6, 'weight': 'bold'}
gl.xlabel_style = {'color': 'white', 'size': 6, 'weight': 'bold'}

# Parse the bulletin and plot it
df = parse_wpc_surface_bulletin('/content/20240207Test_coded_bulletin_SAMd3_hires.dat')
plot_bulletin(ax, df)

ax.set_title(f'WPC Surface Analysis Valid {df.valid.dt.strftime("%HZ %d %b %Y")[0]}')
add_metpy_logo(fig, 50, 50, size='small')
plt.show()

Errors, Traceback, and Logs

No response

dopplershift commented 4 months ago

Never contemplated the need for negative latitudes since WPC didn't document them. 😉 That should be an easy enough update to the parser, we'll see if we can squeeze that into our impending bugfix release.

dopplershift commented 3 months ago

@diegormsouza This has been fixed on the main branch and will be fixed in our next release.

diegormsouza commented 3 months ago

Thanks a lot!

Below, the original image as published by the WPC, followed by the high res coded bulletin and low res coded bulletin.

The plot for the high res bulletin is perfect! For the low res we have additional Highs but these are probably from the original file, I think...

image image image