1212from matplotlib .lines import Line2D
1313from matplotlib .collections import LineCollection
1414from matplotlib .colors import BoundaryNorm , ListedColormap
15+ import cartopy .crs as ccrs
1516import pandas as pd
1617import xarray as xr
1718from sklearn .neighbors import DistanceMetric
@@ -92,7 +93,9 @@ def get_track(self, track_name=None):
9293 for track in self .data :
9394 if track .name == track_name :
9495 return track
95- return self .data
96+
97+ LOGGER .info ('No track with name %s found.' , track_name )
98+ return []
9699
97100 def read_ibtracs_csv (self , file_names ):
98101 """Clear and model tropical cyclone from input csv IBTrACS file.
@@ -203,8 +206,12 @@ def calc_random_walk(self, ens_size=9, ens_amp0=1.5, max_angle=np.pi/10, \
203206 self .data = ens_track
204207 self ._calc_land_params ()
205208 if decay :
206- v_rel , p_rel = self ._calc_land_decay ()
207- self ._apply_land_decay (v_rel , p_rel )
209+ try :
210+ v_rel , p_rel = self ._calc_land_decay ()
211+ self ._apply_land_decay (v_rel , p_rel )
212+ except ValueError as err :
213+ LOGGER .info ('No land decay coefficients could be applied. %s' ,\
214+ str (err ))
208215
209216 def plot (self , title = None ):
210217 """Track over earth. Historical events are blue, probabilistic black.
@@ -215,6 +222,10 @@ def plot(self, title=None):
215222 Returns:
216223 matplotlib.figure.Figure, matplotlib.axes._subplots.AxesSubplot
217224 """
225+ if not self .size :
226+ LOGGER .info ('No tracks to plot' )
227+ return
228+
218229 deg_border = 0.5
219230 fig , axis = plot .make_map ()
220231 axis = axis [0 ][0 ]
@@ -238,11 +249,11 @@ def plot(self, title=None):
238249 track .lat .values ]).T .reshape (- 1 , 1 , 2 )
239250 segments = np .concatenate ([points [:- 1 ], points [1 :]], axis = 1 )
240251 if track .orig_event_flag :
241- track_lc = LineCollection (segments , cmap = cmap , norm = norm ,
242- linestyle = 'solid' )
252+ track_lc = LineCollection (segments , cmap = cmap , norm = norm , \
253+ linestyle = 'solid' , transform = ccrs . PlateCarree (), lw = 2 )
243254 else :
244- track_lc = LineCollection (segments , cmap = cmap , norm = norm ,
245- linestyle = 'dashed' )
255+ track_lc = LineCollection (segments , cmap = cmap , norm = norm , \
256+ linestyle = ':' , transform = ccrs . PlateCarree (), lw = 2 )
246257 track_lc .set_array (track .max_sustained_wind .values )
247258 axis .add_collection (track_lc )
248259
@@ -341,6 +352,8 @@ def _calc_land_params(self):
341352 only_syn (bool, optional): consider only synthetic tracks.
342353 Default: False.
343354 """
355+ if not self .size :
356+ return
344357 deg_buffer = 0.1
345358 min_lat = np .min ([np .min (track .lat .values ) for track in self .data ])
346359 min_lat = max (min_lat - deg_buffer , - 90 )
@@ -381,10 +394,10 @@ def _read_one_csv(self, file_name):
381394 datetimes .append (dt .datetime (int (year ), int (month ), int (day ), \
382395 int (hour )))
383396
384- lat = dfr ['cgps_lat' ].values
385- lon = dfr ['cgps_lon' ].values
386- cen_pres = dfr ['pcen' ].values
387- max_sus_wind = dfr ['vmax' ].values
397+ lat = dfr ['cgps_lat' ].values . astype ( 'float' )
398+ lon = dfr ['cgps_lon' ].values . astype ( 'float' )
399+ cen_pres = dfr ['pcen' ].values . astype ( 'float' )
400+ max_sus_wind = dfr ['vmax' ].values . astype ( 'float' )
388401 max_sus_wind_unit = 'kn'
389402 cen_pres = _missing_pressure (cen_pres , max_sus_wind , lat , lon )
390403
@@ -393,17 +406,23 @@ def _read_one_csv(self, file_name):
393406 tr_ds .coords ['lat' ] = ('time' , lat )
394407 tr_ds .coords ['lon' ] = ('time' , lon )
395408 tr_ds ['time_step' ] = ('time' , dfr ['tint' ].values )
396- tr_ds ['radius_max_wind' ] = ('time' , dfr ['rmax' ].values )
409+ tr_ds ['radius_max_wind' ] = ('time' , dfr ['rmax' ].values . astype ( 'float' ) )
397410 tr_ds ['max_sustained_wind' ] = ('time' , max_sus_wind )
398411 tr_ds ['central_pressure' ] = ('time' , cen_pres )
399- tr_ds ['environmental_pressure' ] = ('time' , dfr ['penv' ].values )
412+ tr_ds ['environmental_pressure' ] = ('time' , \
413+ dfr ['penv' ].values .astype ('float' ))
400414 tr_ds .attrs ['max_sustained_wind_unit' ] = max_sus_wind_unit
401415 tr_ds .attrs ['central_pressure_unit' ] = 'mb'
402416 tr_ds .attrs ['name' ] = name
403417 tr_ds .attrs ['orig_event_flag' ] = bool (dfr ['original_data' ]. values [0 ])
404418 tr_ds .attrs ['data_provider' ] = dfr ['data_provider' ].values [0 ]
405419 tr_ds .attrs ['basin' ] = dfr ['gen_basin' ].values [0 ]
406- tr_ds .attrs ['id_no' ] = float (name .replace ('N' , '0' ). replace ('S' , '1' ))
420+ try :
421+ tr_ds .attrs ['id_no' ] = float (name .replace ('N' , '0' ). \
422+ replace ('S' , '1' ))
423+ except ValueError :
424+ tr_ds .attrs ['id_no' ] = float (str (datetimes [0 ].date ()). \
425+ replace ('-' , '' ))
407426 tr_ds .attrs ['category' ] = set_category (max_sus_wind , \
408427 max_sus_wind_unit )
409428
@@ -822,8 +841,9 @@ def _check_apply_decay_hist_plot(hist_tracks):
822841
823842def _missing_pressure (cen_pres , v_max , lat , lon ):
824843 """Deal with missing central pressures."""
825- if np .argwhere (cen_pres < 0 ).size > 0 :
826- cen_pres = 1024.388 + 0.047 * lat - 0.029 * lon - 0.818 * v_max
844+ if np .argwhere (cen_pres <= 0 ).size > 0 :
845+ cen_pres = 1024.388 + 0.047 * lat - 0.029 * lon - 0.818 * v_max # ibtracs 1980 -2013 (r2=0.91)
846+ # cen_pres = 1024.688+0.055*lat-0.028*lon-0.815*v_max # peduzzi
827847 return cen_pres
828848
829849def set_category (max_sus_wind , max_sus_wind_unit ):
0 commit comments