@@ -20,125 +20,9 @@ def to_array(self):
2020
2121from pygam import GAM , te # pyGAM maintanance lapsed. Waiting for update.
2222
23- parent_dir = os .path .dirname (os .getcwd ())
2423np .random .seed (117 )
2524
2625
27- def ImportOpenairDataExample ():
28- """
29- Example data from the R openair library.
30- See https://www.rdocumentation.org/packages/openair/versions/2.18-2/topics/mydata.
31- Gaseous pollutants are all in ppbv, except CO which is in ppmv.
32- Particle-phase pollutants are in ug/m3.
33- Wind speeds are in m/s.
34- Wind directions are in degrees, with 0/360 being winds from the north.
35- """
36- df = pd .read_csv (parent_dir + "/test_data/openair_test_data.csv" )
37- df = df .drop (columns = ["Unnamed: 0" ])
38- df ["date" ] = pd .to_datetime (df ["date" ])
39- df = df .sort_index ()
40-
41- # Add some jitter to wind directions
42- df ["wd" ] = df ["wd" ] + np .random .uniform (- 10 , 10 , len (df .index ))
43- df ["wd" ] %= 360
44-
45- # Add some jitter to wind speeds
46- df ["ws" ] = df ["ws" ] + np .random .uniform (- 0.1 , 0.1 , len (df .index ))
47- df .loc [df ["ws" ] < 0 , "ws" ] = 0
48-
49- return df
50-
51-
52- def ImportTorontoNO2 ():
53- """Imports test pollution data. The data is from 125 Resources Rd., Toronto, 2023-01-01 to 2023-12-31."""
54- # Import and rename columns
55- pol_df = pd .read_csv (parent_dir + "/test_data/NO2_2023.csv" , skiprows = 7 )
56- pol_df .columns = [
57- "pollutant" ,
58- "naps_id" ,
59- "city" ,
60- "province" ,
61- "lat" ,
62- "lon" ,
63- "date" ,
64- ] + [i for i in range (1 , 25 )]
65-
66- # Choose only Toronto 125 Resources Rd. station
67- pol_df = pol_df .loc [pol_df ["naps_id" ] == 60430 , :]
68-
69- # Wide to long
70- pol_df = pd .melt (
71- pol_df ,
72- id_vars = ["date" ],
73- value_vars = [i for i in range (1 , 25 )],
74- var_name = "hour" ,
75- value_name = "no2_ppbv" ,
76- )
77-
78- # Form and set datetime index
79- pol_df ["datetime" ] = pd .to_datetime (
80- pol_df ["date" ] + " " + (pol_df ["hour" ] - 1 ).astype (str ) + ":00:00"
81- ) + pd .Timedelta ("1h" )
82- pol_df = pol_df .drop (columns = ["date" , "hour" ])
83- pol_df = pol_df .set_index ("datetime" )
84- pol_df = pol_df .sort_index ()
85-
86- # Set missing values to np.nan
87- pol_df ["no2_ppbv" ] = pol_df ["no2_ppbv" ].replace (- 999 , np .nan )
88-
89- return pol_df
90-
91-
92- def ImportTorontoMet ():
93- """Imports test meteorology. The data is from Toronto's Pearson Airport, 2023-01-01 to 2023-12-31."""
94- # Import and rename columns
95- met_df = pd .read_csv (parent_dir + "/test_data/climate-hourly.csv" )
96- met_df = met_df [["UTC_DATE" , "WIND_DIRECTION" , "WIND_SPEED" ]]
97- met_df .columns = ["datetime" , "wind_dir" , "wind_speed" ]
98-
99- # Convert from UTC to EST (pol data is in "local standard time")
100- met_df ["datetime" ] = pd .to_datetime (met_df ["datetime" ])
101- met_df ["datetime" ] = met_df ["datetime" ].dt .tz_localize ("UTC" ).dt .tz_convert ("EST" )
102- met_df ["datetime" ] = met_df ["datetime" ].dt .tz_localize (None )
103- met_df = met_df .set_index ("datetime" )
104- met_df = met_df .sort_index ()
105-
106- # Drop the first row (last hour of prior year)
107- met_df = met_df .iloc [1 :, :]
108-
109- # Convert wind direction from tens of degrees to degrees
110- met_df ["wind_dir_deg" ] = met_df ["wind_dir" ] * 10
111- met_df = met_df .drop (columns = ["wind_dir" ])
112- met_df ["wind_dir_deg" ] = met_df ["wind_dir_deg" ].replace (
113- 0 , np .nan
114- ) # zeros are calms
115-
116- # Add some jitter to wind direction
117- met_df ["wind_dir_deg" ] = met_df ["wind_dir_deg" ] + np .random .uniform (
118- - 10 , 10 , len (met_df .index )
119- )
120- met_df ["wind_dir_deg" ] %= 360
121-
122- # Add some jitter to wind speed and convert from km/h to m/s
123- met_df ["wind_speed" ] = met_df ["wind_speed" ] + np .random .uniform (
124- - 0.5 , 0.5 , len (met_df .index )
125- )
126- met_df .loc [met_df ["wind_speed" ] < 0 , "wind_speed" ] = (
127- 0 # the jittering could introduce negatives
128- )
129- met_df ["wind_speed_m_s" ] = met_df ["wind_speed" ] / 3.6
130- met_df = met_df .drop (columns = ["wind_speed" ])
131-
132- return met_df
133-
134-
135- def LoadTorontoDataExample ():
136- pol_df = ImportTorontoNO2 ()
137- met_df = ImportTorontoMet ()
138- df = pol_df .join (met_df )
139- return df
140-
141-
14226def _makeScatterPlot (xs , ys , zs , vmin , vmax , cmap , colourbar_label , scatter_kwds ):
14327 # Create and return the plot
14428 fig , ax = plt .subplots (1 , 1 , figsize = (8 , 8 ), layout = "constrained" )
0 commit comments