0

My goal is to plot wind barbs only when they exceed 2/3 the max wind speed observed in the domain of interest (this is one part of the standard Miller Composite map).

The code in the MetPy examples that does this for the Miller plot

wspd_500 = mpcalc.wind_speed(u_500, v_500)
wspd_850 = mpcalc.wind_speed(u_850, v_850)


mask_500 = ma.masked_less_equal(wspd_500, 0.66 * np.max(wspd_500)).mask
u_500[mask_500] = np.nan
v_500[mask_500] = np.nan

# 850 hPa
mask_850 = ma.masked_less_equal(wspd_850, 0.66 * np.max(wspd_850)).mask
u_850[mask_850] = np.nan
v_850[mask_850] = np.nan

skip_500 = (slice(None, None, 10), slice(None, None, 10))
skip_850 = (slice(None, None, 8), slice(None, None, 8))

# 500-hPa wind barbs
jet500 = ax.barbs(lon[skip_500], lat[skip_500], u_500[skip_500].m, v_500[skip_500].m, length=6,
                  transform=ccrs.PlateCarree(),
                  color='blue', zorder=9, label='500-hPa Jet Core Winds (kt)')

# 850-hPa wind barbs
jet850 = ax.barbs(lon[skip_850], lat[skip_850], u_850[skip_850].m, v_850[skip_850].m, length=6,
                  transform=ccrs.PlateCarree(),
                  color='k', zorder=8, label='850-hPa Jet Core Winds (kt)')

returns an error

TypeError: len() of unsized object

traced back to the line

u_500[mask_500] = np.nan

To troubleshoot, I printed wspd_500:

[[0.3819355070590973 0.41758668422698975 0.41758668422698975 ... nan nan  nan] [0.3577602505683899 0.4053502082824707 0.4053502082824707 ... nan nan  nan] [0.3433985114097595 0.4025561213493347 0.4025561213493347 ... nan nan  nan] ... [nan nan nan ... nan nan nan] [nan nan nan ... nan nan nan] [nan nan nan ... nan nan nan]] meter / second

which is odd because I'm not sure why all these nan values keep popping up. u_500 and v_500 seem to contain all the relevant values. When I plot using a different method:

ax.barbs(x[wind_slice], y[wind_slice], u_850.metpy.unit_array[wind_slice, wind_slice].to('knots'), v_850.metpy.unit_array[wind_slice, wind_slice].to('knots'), length=6, color = '#ff0000')

I get wind barbs across my entire domain. So I'm skeptical that there is missing data.

Furthermore, when I print mask_500, I get a single False. This should be an array of True or False booleans depending on whether the wind speeds are high or low (at least I think).

So my question is: how can I implement this mask to only plot significantly strong winds at a given pressure level? Why is the mpcalc.wind_speed method returning a bunch of nan values from complete u and v component dataarrays?

For reference in case it's helpful, I'm using HRRR data obtained from the UCAR TDS via siphon.

Jack Sillin
  • 75
  • 1
  • 9

1 Answers1

0

In recreating this, it comes back to nan originating in your HRRR output. I have approximately 5% missing data around the edges of the domain when I pull in current HRRR output over NCSS with siphon. You can check this with numpy.isnan. If you perform the comparison mask_500 = ma.masked_less_equal(wspd_500, 0.66 * np.max(wspd_500)).mask the max will return as nan. Any comparison to nan will return False and so you get your mask indicating that the whole array evaluated as False, the behavior you're seeing. To avoid this, make sure your comparison value is the max of the non-nan values, e.g.,

notnan_mask_500 = np.isfinite(wspd_500)
mask_500 = ma.masked_less_equal(wspd_500, 0.66 * np.max(wspd_500[notnan_mask_500])).mask

which will pull out the maximum finite value of the array and allow the comparison to work! I haven't run all the way through making the map, but this at least returned a valid mask and resulting array.

dcamron
  • 155
  • 5