Skip to article frontmatterSkip to article content

Visualizing Hurricane Ian Using hvPlot

Within this post, we explore how we can use hvPlot to plot data from Hurricane Ian, which will soon make landfall in Florida.

Motivation

By the end of this post, you will be able to recreate the following plot: Hurricane Ian Plot

Imports

import cartopy.crs as ccrs
import geopandas as gpd
import fiona

from siphon.simplewebservice.ndbc import NDBC
import holoviews as hv
import hvplot.pandas
fiona.drvsupport.supported_drivers['libkml'] = 'rw' # enable KML support which is disabled by default
fiona.drvsupport.supported_drivers['LIBKML'] = 'rw' # enable KML support which is disabled by default

hv.extension("bokeh")
Loading...

Access the Data

We are interested in looking at data related to Hurricane Ian, which is currently off the Florida Coast. We want to plot the expected hurricane track, and the some surface observations from buoys, or floating platforms on water!

National Hurricane Center Data

We are using a few different datasets here. Let’s start with the hurricane forecast from the National Hurricane Center, accessible from their Geographic Information Systems (GIS) webpage:

We need to select the kmz files (a Google GIS file standard for the Hurricane Ian cone and track.

The Cone

A forecast cone is defines as the following, from the National Hurricane Center

The cone represents the probable track of the center of a tropical cyclone, and is formed by enclosing the area swept out by a set of circles (not shown) along the forecast track (at 12, 24, 36 hours, etc). The size of each circle is set so that two-thirds of historical official forecast errors over a 5-year sample fall within the circle. The circle radii defining the cones in 2022 for the Atlantic, Eastern North Pacific, and Central North Pacific basins are given in the table below.

One can also examine historical tracks to determine how often the entire 5-day path of a cyclone remains completely within the area of the cone. This is a different perspective that ignores most timing errors. For example, a storm moving very slowly but in the expected direction would still be within the area of the cone, even though the track forecast error could be very large. Based on forecasts over the previous 5 years, the entire track of the tropical cyclone can be expected to remain within the cone roughly 60-70% of the time.

The Best Track

The Best Track Dataset is the best estimated track from the variety of possible scenarios.

Read the Data Using Geopandas

hurricane_cone = gpd.read_file("../data/AL092022_CONE_latest.kmz")
hurricane_track = gpd.read_file("../data/AL092022_TRACK_latest.kmz")
hurricane_track.head()
Loading...

Our hurricane track file includes additional point data - we just need the line (the first row, so let’s filter based on the TCInitLocation

hurricane_track = hurricane_track.dropna(subset=["TCInitLocation"])
hurricane_track
Loading...

Investigate the GeoDataframes

Let’s check out the geodataframe. Notice how it looks like a typical dataframe, with additional geometry information.

hurricane_cone
Loading...

We can create static matplotlib plots using the .plot() method.

hurricane_cone.plot()
hurricane_track.plot();
<Figure size 640x480 with 1 Axes><Figure size 640x480 with 1 Axes>

Access NOAA Buoy Data

The National Oceanic and Atmospheric Administation (NOAA) has a buoy dataset (from the National Data Buoy Center), which includes observations from around the world. We can access this data using siphon, a tool developed by the Unidata Program Center which makes accessing this dataset much easier.

We can use the .lastest_observations() method from the NDBC module to access the latest data.

buoy_df = NDBC.latest_observations()
buoy_df
Loading...

Filter the Dataset

We are interested in locations that have water_temperature values, so we filter using .dropna()

buoy_df = buoy_df.dropna(subset=["water_temperature"])
buoy_df.plot.scatter(x='longitude', y='latitude', c='water_temperature')
<Figure size 640x480 with 2 Axes>

Plot our Data using hvPlot

Let’s move to interactive visualization!

Plot the Hurricane Cone and Track Using hvPlot

We can do better than just static plots - let’s create an interactive one using hvPlot!

hurricane_cone.hvplot(color='None',
                      line_width=3,
                      coastline=True,
                      xlim=(-95, -65),
                      ylim=(20, 40),
                      label='NHC Forecast Cone for Hurricane Ian',
                      projection=ccrs.PlateCarree(),
                      features=["land", "ocean"])
Loading...

And the same for the best estimated track

hurricane_track_plot = hurricane_track.hvplot(line_color='Red',
                                              color="None",
                                              line_width=3,
                                              coastline=True,
                                              xlim=(-95, -65),
                                              ylim=(20, 40),
                                              label='NHC Forecast Track for Hurricane Ian',
                                              projection=ccrs.PlateCarree(),
                                              features=["land", "ocean"])
hurricane_track_plot
Loading...

We still need a title though, since this does not tell us what time this is valid... this information is in the dataframe!

hurricane_cone.advisoryDate
0 800 PM EDT Tue Sep 27 2022 Name: advisoryDate, dtype: object

Combine our Forecast Cone and Track Plots

Let’s add the titles, and combine our plots.

hurricane_track_plot = hurricane_track.hvplot(line_color='Red',
                                              color="None",
                                              line_width=3,
                                              coastline=True,
                                              xlim=(-95, -65),
                                              ylim=(20, 40),
                                              title=f'NHC Forecast Valid: {hurricane_track.pubAdvTime.values[0]}',
                                              label='NHC Forecast Track for Hurricane Ian',
                                              projection=ccrs.PlateCarree()
                                             )

hurricane_cone_plot = hurricane_cone.hvplot(color='None',
                                            line_width=3,
                                            line_color='Black',
                                            coastline=True,
                                            xlim=(-95, -65),
                                            ylim=(20, 40),
                                            title=f"NHC Forecast Valid {hurricane_cone.advisoryDate.values[0]}",
                                            label='NHC Forecast Cone for Hurricane Ian',
                                            projection=ccrs.PlateCarree(),
                                            features=["land", "ocean"])

hurricane_plot = (hurricane_cone_plot * hurricane_track_plot)
hurricane_plot
Loading...

Plot the Buoy Data using hvPlot

buoy_plot = buoy_df.hvplot.points(x='longitude',
                                  y='latitude',
                                  c='water_temperature',
                                  cmap='inferno',
                                  label='NOAA Buoy Locations',
                                  title='NOAA Buoy Water Temperature',
                                  clabel='Temperature (degC)',
                                  geo=True,
                                  coastline=True,
                                  projection=ccrs.PlateCarree(),
                                  xlim=(-95, -65),
                                  ylim=(20, 40),
                                  clim=(20, 35))
buoy_plot
Loading...

Final Visualization

Let’s put it all together! We combine our plots using the * operator.

hurricane_plot * buoy_plot
Loading...

Conclusions

Within this example, we explored visualizing data from the National Hurricane Center, and from the National Data Buoy Center. We encourage you to try this out on your own.

In the future, it would be nice to add other datasets, such as weather radar data, onto these plots as well.