Data are pulled from SECOORA ERDDAP using a 48-hour window ending at the latest available ERDDAP time (2026-07-27 05:06 EDT). The buoy map below shows the most recent non-missing temperature value for each station. Interpolated fields use snapshots at 06:00, 12:00, 18:00, and 24:00 US Eastern on 2026-07-26.
if (nrow(temperature_data) ==0) {stop("No temperature data returned from ERDDAP for the current time window.")}temperature_data |>arrange(desc(time)) |>mutate(time =format_ndbc_time(time),temperature =number(temperature, accuracy =0.1) ) |>select(Station = station, `Station ID`= station_id, Time = time, `Temperature (°C)`= temperature) |>kable()
Temperature is shown in degrees Celsius. Cooler values (blue) and warmer values (red) reflect spatial variation across the buoy network.
Interpolated temperature field
The fields below use DIVAnd (Data-Interpolating Variational Analysis) with bathymetry masking, following the same approach as sfer-mbon-oxygen: ~0.01° horizontal grid resolution (~1 km), a two-scale analysis (smooth 0.08° background + 0.035° local anomalies with epsilon2 = 0.01), and interpolation run separately within each connected sea component so distant buoys do not smooth over local features. Land is masked using Natural Earth 10 m coastlines plus NOAA BlueTopo 4 m bathymetry (8 m tiles fill gaps); cells with missing bathymetry or elevation ≥ −0.2 m are treated as land. Sea cells are extended along water paths from each buoy (not across islands), then short bridges are added only through BlueTopo water cells (elevation < −0.2 m) to connect nearby stations still isolated from the main field.
Four panels show the interpolated field at 06:00, 12:00, 18:00, and 24:00 US Eastern on 2026-07-26. Each panel uses buoy observations closest to that hour.
Code
temperature_fields <-interpolate_ndbc_hourly_fields( ndbc_data$snapshots,value_col ="temperature")for (result in temperature_fields) {cat(sprintf("Hour %02d: %d field cells, %d observations\n", result$hour,if (is.null(result$field)) 0L elsenrow(result$field),nrow(result$observations) ) )}
Hour 06: 1194 field cells, 19 observations
Hour 12: 1194 field cells, 19 observations
Hour 18: 1194 field cells, 19 observations
Hour 24: 1194 field cells, 19 observations
Code
if (all(vapply(temperature_fields, function(x) is.null(x$field) ||nrow(x$field) ==0, logical(1)))) {stop("No interpolated temperature fields were produced.")}plot_ndbc_field_panels( temperature_fields,value_col ="temperature",legend_title ="Temperature (°C)",popup_suffix =" °C",palette =c("#313695", "#74add1", "#abd9e9", "#fee090", "#f46d43", "#a50026"),label_fn = format_hour_panel_label)
2026-07-26 06:00 EDT
2026-07-26 12:00 EDT
2026-07-26 18:00 EDT
2026-07-26 24:00 EDT
The colored grids show the DIVAnd-interpolated field at each hour; circle markers show the buoy observations used as input.