k32462 commited on
Commit
5d94970
·
verified ·
1 Parent(s): 4e82dbd

upload weather_example.py

Browse files
Files changed (1) hide show
  1. weather_example.py +618 -0
weather_example.py ADDED
@@ -0,0 +1,618 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import polars as pl
4
+ import requests
5
+ from datetime import datetime, timedelta
6
+ import plotly.express as px
7
+
8
+ # Create a sample DataFrame
9
+ data = {
10
+ 'city': ['Rexburg', 'Rexburg', 'Rexburg', 'Provo', 'Provo', 'Laie', 'Laie'],
11
+ 'date': ['2024-07-01', '2024-07-01', '2024-07-02', '2024-07-01', '2024-07-01', '2024-07-01', '2024-07-01'],
12
+ 'hour': [0, 1, 0, 0, 1, 0, 1],
13
+ 'temperature': [15, 14, 16, 20, 19, 25, 24]
14
+ }
15
+
16
+ # Create Polars DataFrame
17
+ df = pl.DataFrame(data)
18
+
19
+ # Convert date column to datetime
20
+ df = df.with_columns(pl.col("date").str.strptime(pl.Date, "%Y-%m-%d"))
21
+
22
+ # HISTORICAL FORECAST
23
+
24
+ # Define the locations with their respective latitude and longitude
25
+ locations = {
26
+ "Rexburg": {"latitude": 43.8260, "longitude": -111.7897},
27
+ "Provo": {"latitude": 40.2338, "longitude": -111.6585},
28
+ "Laie": {"latitude": 21.6478, "longitude": -157.9234}
29
+ }
30
+
31
+ # Function to get historical forecast data
32
+ def get_historical_forecast_data(location, latitude, longitude, start_date, end_date):
33
+ api_url = "https://api.open-meteo.com/v1/forecast"
34
+ params = {
35
+ "latitude": latitude,
36
+ "longitude": longitude,
37
+ "start_date": start_date,
38
+ "end_date": end_date,
39
+ "hourly": "temperature_2m",
40
+ "timezone": "America/Denver" # Adjust timezone as needed
41
+ }
42
+
43
+ response = requests.get(api_url, params=params)
44
+ data = response.json()
45
+
46
+ # Extract hourly data
47
+ hourly_data = data['hourly']
48
+ timestamps = hourly_data['time']
49
+ temperatures = hourly_data['temperature_2m']
50
+
51
+ # Create DataFrame for historical forecast data
52
+ historical_forecast_df = pl.DataFrame({
53
+ "location": location,
54
+ "timestamp": timestamps,
55
+ "temperature_2m": temperatures,
56
+ "data_type": "historical forecast" # Label the data as historical forecast
57
+ })
58
+
59
+ return historical_forecast_df
60
+
61
+ # Define the date range for historical data
62
+ start_date = "2024-06-01"
63
+ end_date = "2024-07-15"
64
+
65
+ # Fetch and concatenate historical forecast data for all locations
66
+ forecast_dfs = [get_historical_forecast_data(loc, info['latitude'], info['longitude'], start_date, end_date) for loc, info in locations.items()]
67
+ forecast_combined_df = pl.concat(forecast_dfs)
68
+
69
+ # Process timestamp to extract date, day of the week, and hour of day
70
+ forecast_combined_df = forecast_combined_df.with_columns([
71
+ pl.col("timestamp").str.strptime(pl.Datetime).alias("datetime"),
72
+ pl.col("timestamp").str.strptime(pl.Datetime).dt.date().alias("date"),
73
+ pl.col("timestamp").str.strptime(pl.Datetime).dt.weekday().alias("day_of_week"),
74
+ pl.col("timestamp").str.strptime(pl.Datetime).dt.hour().alias("hour_of_day"),
75
+ (pl.col("temperature_2m") * (9 / 5) + 32).alias("temperature_2m")
76
+ ])
77
+
78
+ # Select and reorder columns
79
+ forecast_combined_df = forecast_combined_df.select([
80
+ "location", "datetime", "date", "day_of_week", "hour_of_day", "temperature_2m", "data_type"
81
+ ])
82
+
83
+ # Show the updated DataFrame
84
+ print(forecast_combined_df)
85
+
86
+
87
+
88
+ # HISTORICAL DATA
89
+
90
+ locations = {
91
+ "Rexburg": {"latitude": 43.8260, "longitude": -111.7897},
92
+ "Provo": {"latitude": 40.2338, "longitude": -111.6585},
93
+ "Laie": {"latitude": 21.6478, "longitude": -157.9234}
94
+ }
95
+
96
+ # Function to get historical weather data
97
+ def get_historical_weather_data(location, latitude, longitude, start_date, end_date):
98
+ api_url = "https://api.open-meteo.com/v1/forecast"
99
+ params = {
100
+ "latitude": latitude,
101
+ "longitude": longitude,
102
+ "start_date": start_date,
103
+ "end_date": end_date,
104
+ "hourly": "temperature_2m,dewpoint_2m,wind_gusts_10m,visibility,cloudcover,precipitation_probability,relative_humidity_2m,sunshine_duration,vapour_pressure_deficit,rain,soil_temperature_0_to_7cm",
105
+ "timezone": "America/Denver" # Adjust timezone as needed
106
+ }
107
+
108
+ response = requests.get(api_url, params=params)
109
+ data = response.json()
110
+
111
+ # Check if 'hourly' data is available
112
+ if 'hourly' not in data:
113
+ raise KeyError(f"'hourly' key not found in API response for {location}")
114
+
115
+ # Extract hourly data
116
+ hourly_data = data['hourly']
117
+ timestamps = hourly_data['time']
118
+ temperatures = hourly_data.get('temperature_2m', [])
119
+ dewpoints = hourly_data.get('dewpoint_2m', [])
120
+ wind_gusts = hourly_data.get('wind_gusts_10m', [])
121
+ visibility = hourly_data.get('visibility', [])
122
+ cloud_cover = hourly_data.get('cloudcover', [])
123
+ precipitation_prob = hourly_data.get('precipitation_probability', [])
124
+ relative_humidity = hourly_data.get('relative_humidity_2m', [])
125
+ sunshine_duration = hourly_data.get('sunshine_duration', [])
126
+ vapor_pressure = hourly_data.get('vapour_pressure_deficit',[])
127
+ rain = hourly_data.get('rain', [])
128
+ soil_temp = hourly_data.get('soil_temperature_0_to_7cm',[])
129
+
130
+ # Create DataFrame for historical weather data
131
+ historical_weather_df = pl.DataFrame({
132
+ "location": location,
133
+ "timestamp": timestamps,
134
+ "temperature_2m": temperatures,
135
+ "dewpoint_2m": dewpoints,
136
+ "wind_gusts_10m": wind_gusts,
137
+ "visibility": visibility,
138
+ "cloudcover": cloud_cover,
139
+ "precipitation_probability": precipitation_prob,
140
+ "relative_humidity_2m": relative_humidity,
141
+ "sunshine_duration": sunshine_duration,
142
+ "vapor_pressure": vapor_pressure,
143
+ "rain": rain,
144
+ "soil_temp": soil_temp,
145
+ "data_type": "historical" # Label the data as historical
146
+ })
147
+
148
+ return historical_weather_df
149
+
150
+ # Define the date range for historical data
151
+ start_date = "2024-06-01"
152
+ end_date = "2024-07-15"
153
+
154
+ # Fetch and concatenate historical weather data for all locations
155
+ data_frames = []
156
+ for loc, info in locations.items():
157
+ try:
158
+ df = get_historical_weather_data(loc, info['latitude'], info['longitude'], start_date, end_date)
159
+ data_frames.append(df)
160
+ except KeyError as e:
161
+ print(e)
162
+ continue
163
+
164
+ if data_frames:
165
+ combined_df = pl.concat(data_frames)
166
+ else:
167
+ raise ValueError("No data fetched for any location.")
168
+
169
+ # Process timestamp to extract date, day of the week, and hour of day
170
+ combined_df = combined_df.with_columns([
171
+ pl.col("timestamp").str.strptime(pl.Datetime).alias("datetime"),
172
+ pl.col("timestamp").str.strptime(pl.Datetime).dt.date().alias("date"),
173
+ pl.col("timestamp").str.strptime(pl.Datetime).dt.weekday().alias("day_of_week"),
174
+ pl.col("timestamp").str.strptime(pl.Datetime).dt.hour().alias("hour_of_day"),
175
+ (pl.col("temperature_2m") * (9 / 5) + 32).alias("temperature_2m_f") # Convert temperature to Fahrenheit
176
+ ])
177
+
178
+ # Select and reorder columns
179
+ weather_combined_df = combined_df.select([
180
+ "location", "datetime", "date", "day_of_week", "hour_of_day", "temperature_2m_f", "dewpoint_2m", "wind_gusts_10m", "visibility", "cloudcover", "precipitation_probability", "relative_humidity_2m", "sunshine_duration",'vapor_pressure','rain' ,'soil_temp',"data_type"
181
+ ])
182
+
183
+ # Show the updated DataFrame
184
+ print(weather_combined_df)
185
+
186
+
187
+
188
+
189
+
190
+
191
+
192
+ # COMBINING DATA
193
+
194
+ df = forecast_combined_df.join(
195
+ weather_combined_df,
196
+ left_on=["location",'date','day_of_week','hour_of_day'],
197
+ right_on=["location",'date','day_of_week','hour_of_day'],
198
+ how="inner"
199
+ )
200
+
201
+ day_name_map = {0: "Monday", 1: "Tuesday", 2: "Wednesday", 3: "Thursday", 4: "Friday", 5: "Saturday", 6: "Sunday"}
202
+
203
+ df = df.with_columns([
204
+ pl.col("temperature_2m").alias("historical_forecast"),
205
+ pl.col("temperature_2m_f").alias("historical"),
206
+ pl.col('date').dt.weekday().map_dict(day_name_map).alias('day_of_week')
207
+ ])
208
+
209
+ df= df.drop(["temperature_2m", "temperature_2m_f",'data_type','data_type_right'])
210
+
211
+
212
+
213
+ # CITY TABLES
214
+
215
+ rexburg = df.filter(pl.col('location') == 'Rexburg')
216
+ rexburg = rexburg.select([
217
+ pl.col('date').alias('Date'),
218
+ pl.col('hour_of_day').alias('Hour'),
219
+ pl.col('historical_forecast').alias('Historical_Forecast'),
220
+ pl.col('historical').alias('Historical')
221
+ ])
222
+
223
+ laie = df.filter(pl.col('location') == 'Laie')
224
+ laie = laie.select([
225
+ pl.col('date').alias('Date'),
226
+ pl.col('hour_of_day').alias('Hour'),
227
+ pl.col('historical_forecast').alias('Historical_Forecast'),
228
+ pl.col('historical').alias('Historical')
229
+ ])
230
+
231
+ provo = df.filter(pl.col("location") == 'Provo')
232
+ provo = provo.select([
233
+ pl.col('date').alias('Date'),
234
+ pl.col('hour_of_day').alias('Hour'),
235
+ pl.col('historical_forecast').alias('Historical_Forecast'),
236
+ pl.col('historical').alias('Historical')
237
+ ])
238
+
239
+
240
+
241
+ # Sidebar
242
+
243
+ df_streamlit_select = df.groupby('location','date').agg(
244
+ pl.col('historical').max().alias('daily_high')
245
+ )
246
+
247
+ df_streamlit_select = df_streamlit_select.sort(['location', 'date'])
248
+
249
+
250
+
251
+
252
+
253
+
254
+ # STREAMLIT TABLES
255
+
256
+ rexburg_streamlit = rexburg.to_pandas()
257
+ laie_streamlit = laie.to_pandas()
258
+ provo_streamlit = provo.to_pandas()
259
+
260
+ def main():
261
+ st.title("Weather Data: Historical Vs Historical Forecast")
262
+
263
+ # Create three columns for side-by-side display
264
+ col1, col2, col3 = st.columns(3)
265
+
266
+ # Display each DataFrame in its respective column
267
+ with col1:
268
+ st.write("### Rexburg Data Table")
269
+ st.dataframe(rexburg_streamlit)
270
+
271
+ with col2:
272
+ st.write("### Laie Data Table")
273
+ st.dataframe(laie_streamlit)
274
+
275
+ with col3:
276
+ st.write("### Provo Data Table")
277
+ st.dataframe(provo_streamlit)
278
+
279
+ if __name__ == "__main__":
280
+ main()
281
+
282
+
283
+
284
+ # ALL CITIES
285
+
286
+ all_cities = df.select([
287
+ pl.col('location').alias('City'),
288
+ pl.col('date').alias('Date'),
289
+ pl.col('hour_of_day').alias('Hour'),
290
+ pl.col('historical').alias('Temperature')
291
+ ])
292
+
293
+ all_cities = all_cities.sort(by = ['Date','Hour'])
294
+
295
+ cities_streamlit = all_cities.to_pandas()
296
+
297
+
298
+
299
+ # SIDE BAR
300
+
301
+ st.sidebar.title("Filters")
302
+
303
+ df_streamlit_select = df.groupby('location','date').agg(
304
+ pl.col('historical').max().alias('daily_high')
305
+ )
306
+
307
+ df_streamlit_select = df_streamlit_select.sort(['location', 'date'])
308
+
309
+ kpi_streamlit = df.to_pandas()
310
+
311
+
312
+ # Create date range selection widget with unique key
313
+
314
+ date_min = kpi_streamlit['date'].min()
315
+ date_max = kpi_streamlit['date'].max()
316
+
317
+ # Create city selection widget
318
+ cities = kpi_streamlit['location'].unique()
319
+ selected_city = st.sidebar.selectbox('Select a city', cities, key='city_selector')
320
+
321
+ date_min = kpi_streamlit['date'].min()
322
+ date_max = kpi_streamlit['date'].max()
323
+ selected_dates = st.sidebar.date_input('Select start and end date', [date_min, date_max], key='date_range_selector')
324
+
325
+ metrics = [
326
+ 'dewpoint_2m',
327
+ 'wind_gusts_10m',
328
+ 'visibility',
329
+ 'cloudcover',
330
+ 'precipitation',
331
+ 'relative_humidity_2m',
332
+ 'sunshine_duration',
333
+ 'vapor_pressure',
334
+ 'rain',
335
+ 'soil_temp'
336
+ ]
337
+
338
+
339
+ selected_metric = st.sidebar.selectbox('Select a metric', metrics, key='metric_selector')
340
+
341
+ dow_data = df.to_pandas()
342
+
343
+ days_of_week = dow_data['day_of_week'].unique()
344
+ selected_day = st.sidebar.selectbox('Select a day of the week', days_of_week)
345
+
346
+
347
+ # Create a widget for selecting the weather variable
348
+ weather_variables = [
349
+ "dewpoint_2m", "wind_gusts_10m", "visibility",
350
+ "cloudcover", "precipitation_probability",
351
+ "relative_humidity_2m", "sunshine_duration",
352
+ 'vapor_pressure','soil_temp',
353
+ ]
354
+ selected_variable = st.sidebar.selectbox('Select a weather variable', weather_variables)
355
+
356
+
357
+
358
+ ##### Interactive Dashboard
359
+
360
+ # Line Chart
361
+
362
+
363
+ df_pandas = df_streamlit_select.to_pandas()
364
+
365
+
366
+ # Create date range selection widget
367
+ date_min = df_pandas['date'].min()
368
+ date_max = df_pandas['date'].max()
369
+ selected_dates = st.date_input('Select date range', [date_min, date_max])
370
+
371
+ # Filter data based on user input
372
+ filtered_df = df_streamlit_select.filter(
373
+ (pl.col('date') >= pl.lit(pd.to_datetime(selected_dates[0]))) &
374
+ (pl.col('date') <= pl.lit(pd.to_datetime(selected_dates[1])))
375
+ )
376
+
377
+ # Convert filtered Polars DataFrame to Pandas DataFrame for Streamlit display
378
+ filtered_df_pandas = filtered_df.to_pandas()
379
+
380
+ # Create a line chart using Plotly Express with multiple lines
381
+ fig = px.line(filtered_df_pandas, x='date', y='daily_high', color='location',
382
+ title='Daily High Temperatures by Location')
383
+
384
+ fig.update_layout(
385
+ xaxis_title='Date',
386
+ yaxis_title='Daily High Temperature (°F)'
387
+ )
388
+
389
+ # Show the Plotly chart in Streamlit
390
+ st.plotly_chart(fig, use_container_width=True)
391
+
392
+
393
+
394
+ # BOX PLOT
395
+
396
+ hour_df = df.select(
397
+ pl.col('location'),
398
+ pl.col('datetime'),
399
+ pl.col('date'),
400
+ pl.col('historical')
401
+ )
402
+
403
+ df_pandas = hour_df.to_pandas()
404
+
405
+ fig = px.box(
406
+ df_pandas,
407
+ x='location',
408
+ y='historical',
409
+ title='Hourly Temperature Distribution by Location',
410
+ labels={'location': 'Location', 'historical': 'Hourly Temperature'}
411
+ )
412
+
413
+ # Display the boxplot in Streamlit
414
+ st.plotly_chart(fig)
415
+
416
+
417
+
418
+ # HISTOGRAM
419
+
420
+ fig = px.histogram(
421
+ df_pandas,
422
+ x='historical',
423
+ facet_col='location',
424
+ title='Histogram of Historical Temperatures by Location',
425
+ labels={'historical': 'Historical Temperature', 'location': 'Location', 'count':'Frequency'},
426
+ nbins=30 # Adjust the number of bins as needed
427
+ )
428
+
429
+ fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
430
+
431
+ # Display the faceted histogram in Streamlit
432
+ st.plotly_chart(fig)
433
+
434
+
435
+
436
+ # MAX VALUE
437
+
438
+ # Convert Polars DataFrame to Pandas for Streamlit use
439
+
440
+ # Create date range selection widget with unique key
441
+
442
+ # Filter data based on user input
443
+ filtered_df = kpi_streamlit[
444
+ (kpi_streamlit['location'] == selected_city) &
445
+ (kpi_streamlit['date'] >= pd.to_datetime(selected_dates[0])) &
446
+ (kpi_streamlit['date'] <= pd.to_datetime(selected_dates[1]))
447
+ ]
448
+
449
+ # Get the maximum value for the selected metric
450
+ max_value = filtered_df[selected_metric].max()
451
+
452
+ # Create and display a gauge chart using Plotly Express
453
+ fig = px.bar(
454
+ x=[selected_metric.replace('_', ' ').title()],
455
+ y=[max_value],
456
+ labels={'x': selected_metric.replace('_', ' ').title(), 'y': 'Value'},
457
+ title=f"Max {selected_metric.replace('_', ' ').title()}",
458
+ color_discrete_sequence=['darkblue']
459
+ )
460
+
461
+ # Customize the layout to make it look like a gauge
462
+ fig.update_layout(
463
+ xaxis=dict(
464
+ tickvals=[],
465
+ title=''
466
+ ),
467
+ yaxis=dict(
468
+ tickvals=[],
469
+ title='',
470
+ range=[0, max_value * 1.2]
471
+ ),
472
+ plot_bgcolor='white'
473
+ )
474
+
475
+ import plotly.graph_objects as go
476
+
477
+ fig = go.Figure(go.Indicator(
478
+ mode = "gauge+number",
479
+ value = max_value,
480
+ domain = {'x': [0, 1], 'y': [0, 1]},
481
+ title={'text': f"Max {selected_metric.replace('_', ' ').title()}: {max_value}"}))
482
+
483
+
484
+
485
+
486
+ # MIN VALUE
487
+
488
+ min_value = filtered_df[selected_metric].min()
489
+
490
+ # Create and display a gauge chart using Plotly Express
491
+ thing = px.bar(
492
+ x=[selected_metric.replace('_', ' ').title()],
493
+ y=[min_value],
494
+ labels={'x': selected_metric.replace('_', ' ').title(), 'y': 'Value'},
495
+ title=f"Min {selected_metric.replace('_', ' ').title()}",
496
+ color_discrete_sequence=['darkblue']
497
+ )
498
+
499
+ # Customize the layout to make it look like a gauge
500
+ thing.update_layout(
501
+ xaxis=dict(
502
+ tickvals=[],
503
+ title=''
504
+ ),
505
+ yaxis=dict(
506
+ tickvals=[],
507
+ title='',
508
+ range=[0, min_value * 1.2]
509
+ ),
510
+ plot_bgcolor='white'
511
+ )
512
+
513
+ import plotly.graph_objects as go
514
+
515
+ thing = go.Figure(go.Indicator(
516
+ mode = "gauge+number",
517
+ value = min_value,
518
+ domain = {'x': [0, 1], 'y': [0, 1]},
519
+ title={'text': f"Min {selected_metric.replace('_', ' ').title()}: {min_value}"}))
520
+
521
+ thing = go.Figure(go.Indicator(
522
+ mode = "gauge+number",
523
+ value = min_value,
524
+ domain = {'x': [0, 1], 'y': [0, 1]},
525
+ title={'text': f"Min {selected_metric.replace('_', ' ').title()}: {min_value}"},
526
+ gauge={
527
+ 'axis': {'range': [None, min_value * 1.2]},
528
+ 'bar': {'color': 'red'}
529
+ }
530
+ ))
531
+
532
+
533
+
534
+
535
+ # MAX & MIN DISPLAY
536
+
537
+ col1, col2 = st.columns(2)
538
+
539
+ with col1:
540
+ st.plotly_chart(fig)
541
+
542
+ with col2:
543
+ st.plotly_chart(thing)
544
+
545
+
546
+
547
+ # Additional Inputs
548
+
549
+
550
+
551
+ st.title("Average Temperature by City")
552
+
553
+ # Create day of the week slicer
554
+
555
+ # Filter data based on the selected day of the week
556
+ filtered_df = dow_data[dow_data['day_of_week'] == selected_day]
557
+
558
+ # Calculate average temperature for each city
559
+ avg_temp_per_city = filtered_df.groupby('location')['historical'].mean().reset_index()
560
+
561
+ # Create bar chart
562
+ my_chart = px.bar(
563
+ avg_temp_per_city,
564
+ x='location',
565
+ y='historical',
566
+ labels={'location': 'City', 'historical': 'Average Temperature (°F)'},
567
+ title=f"Average Temperature for Each City on {selected_day}",
568
+ color='historical',
569
+ color_continuous_scale=px.colors.sequential.Plasma
570
+ )
571
+
572
+ # Show the bar chart
573
+ # st.plotly_chart(fig)
574
+
575
+
576
+
577
+
578
+ # Conditions Visualizations
579
+
580
+ conditions_data = df.to_pandas()
581
+
582
+ conditions_data['day_of_week'] = pd.Categorical(conditions_data['day_of_week'], categories=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], ordered=True)
583
+
584
+
585
+ # Filter the DataFrame for the selected weather variable and calculate the average for each day of the week
586
+ filtered_df = conditions_data.groupby(['day_of_week', 'location'])[selected_variable].mean().reset_index()
587
+
588
+ # Create a line chart
589
+ bobby = px.line(
590
+ filtered_df,
591
+ x='day_of_week',
592
+ y=selected_variable,
593
+ color='location',
594
+ title=f"Average {selected_variable.replace('_', ' ').title()} by Day of the Week",
595
+ labels={selected_variable: f'Average {selected_variable.replace("_", " ").title()}'}
596
+ )
597
+
598
+ # Ensure the x-axis has the correct order for days of the week
599
+ bobby.update_xaxes(
600
+ title = 'Day of Week',
601
+ categoryorder='array',
602
+ categoryarray=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'])
603
+
604
+
605
+ # Display the line chart
606
+ # st.plotly_chart(bobby)
607
+
608
+
609
+
610
+ # display last 2 visualizations
611
+
612
+ col1, col2 = st.columns(2)
613
+
614
+ with col1:
615
+ st.plotly_chart(my_chart)
616
+
617
+ with col2:
618
+ st.plotly_chart(bobby)