11import datetime
2+ import io
23import logging
34from pathlib import Path
45
56import matplotlib
67import matplotlib .pyplot as plt
78import mpld3
89import numpy as np
10+ import PIL .Image
911import pygrib
1012from jinja2 import Environment , PackageLoader , select_autoescape
1113from tqdm import tqdm
1214
1315from wavey .common import DATETIME_FORMAT , FEET_PER_METER , TZ_PACIFIC , TZ_UTC , setup_logging
1416from wavey .grib import NUM_DATA_POINTS , ForecastType , read_forecast_data
15- from wavey .map import DEFAULT_ARROW_LENGTH , Map
17+ from wavey .map import DEFAULT_ARROW_LENGTH , RESOLUTION , Map
1618from wavey .nwfs import download_forecast , get_most_recent_forecast
1719
1820# Force non-interactive backend to keep consistency between local and github actions
@@ -43,10 +45,30 @@ def utc_to_pt(dt: datetime.datetime) -> datetime.datetime:
4345 return dt .astimezone (tz = TZ_PACIFIC )
4446
4547
48+ def savefig (path : Path ) -> None :
49+ """
50+ Save matplotlib figure to PNG file.
51+
52+ We perform a bit of optimization to make the output filesize smaller
53+ without sacrificing quality.
54+
55+ Args:
56+ path: Path to output PNG file.
57+ """
58+
59+ bts = io .BytesIO ()
60+ plt .savefig (bts , format = "png" )
61+
62+ with PIL .Image .open (bts ) as img :
63+ img2 = img .convert ("RGB" ).convert ("P" , palette = PIL .Image .Palette .ADAPTIVE )
64+ img2 .save (path , format = "png" )
65+
66+
4667def main (
4768 grib_path : Path | None = None ,
4869 / ,
4970 out_dir : Path = Path ("_site" ),
71+ resolution : RESOLUTION = "h" ,
5072) -> None :
5173 """
5274 Create plots for significant wave height.
@@ -56,8 +78,13 @@ def main(
5678 https://nomads.ncep.noaa.gov/pub/data/nccf/com/nwps/prod/. If none,
5779 will download the most recent one to the current directory.
5880 out_dir: Path to output directory.
81+ resolution: Resolution of the coastline map. Options are crude, low,
82+ intermediate, high, and full.
5983 """
6084
85+ if resolution != "f" :
86+ LOG .warning ("Not drawing full resolution coastlines. Use the flag '--resolution f'" )
87+
6188 out_dir .mkdir (parents = True , exist_ok = True )
6289
6390 # Download data, if needed
@@ -126,6 +153,7 @@ def main(
126153 lat_max_idx = 110 ,
127154 lon_min_idx = 20 ,
128155 lon_max_idx = 70 ,
156+ resolution = resolution ,
129157 )
130158
131159 LOG .info ("Drawing Breakwater map" )
@@ -140,6 +168,7 @@ def main(
140168 lat_max_idx = BREAKWATER_LAT_IDX + 3 ,
141169 lon_min_idx = BREAKWATER_LON_IDX - 2 ,
142170 lon_max_idx = BREAKWATER_LON_IDX + 3 ,
171+ resolution = resolution ,
143172 draw_arrows_length = DEFAULT_ARROW_LENGTH / 3 ,
144173 draw_arrows_stride = 1 ,
145174 )
@@ -157,6 +186,7 @@ def main(
157186 lat_max_idx = MONASTERY_LAT_IDX + 4 ,
158187 lon_min_idx = MONASTERY_LON_IDX - 3 ,
159188 lon_max_idx = MONASTERY_LON_IDX + 2 ,
189+ resolution = resolution ,
160190 draw_arrows_length = DEFAULT_ARROW_LENGTH / 3 ,
161191 draw_arrows_stride = 1 ,
162192 )
@@ -176,7 +206,7 @@ def main(
176206 map_mon .update (hour_i )
177207
178208 ax_main .set_title (f"Significant wave height (ft) and wave direction\n Hour { hour_i :03} -- { pacific_time_str } " )
179- plt . savefig (plot_dir / f"{ hour_i } .png" )
209+ savefig (plot_dir / f"{ hour_i } .png" )
180210
181211 # Get current time
182212
0 commit comments