nakas commited on
Commit
de870a3
·
verified ·
1 Parent(s): f080b01

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +94 -18
app.py CHANGED
@@ -2,27 +2,27 @@
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
 
5
  from datetime import datetime, timedelta
6
  import plotly.express as px
 
 
7
 
8
  def get_weather_data(station_id, hours=72):
9
  """
10
  Fetch weather data from NWS API
11
  """
12
- # NWS API requires a user agent header
13
  headers = {
14
  'User-Agent': '(Weather Data Fetcher, contact@yourdomain.com)',
15
  'Accept': 'application/json'
16
  }
17
 
18
- # First, get the station details
19
  station_url = f'https://api.weather.gov/stations/{station_id}'
20
  try:
21
  response = requests.get(station_url, headers=headers)
22
  response.raise_for_status()
23
  station_data = response.json()
24
 
25
- # Get observations
26
  observations_url = f'https://api.weather.gov/stations/{station_id}/observations'
27
  params = {
28
  'limit': hours,
@@ -34,7 +34,6 @@ def get_weather_data(station_id, hours=72):
34
 
35
  data = response.json()
36
 
37
- # Extract relevant information
38
  records = []
39
  for obs in data['features']:
40
  props = obs['properties']
@@ -44,28 +43,99 @@ def get_weather_data(station_id, hours=72):
44
  'relative_humidity': props['relativeHumidity']['value'],
45
  'wind_speed': props['windSpeed']['value'],
46
  'wind_direction': props['windDirection']['value'],
47
- 'barometric_pressure': props['barometricPressure']['value']
 
 
48
  }
49
  records.append(record)
50
 
51
  df = pd.DataFrame(records)
52
  df['timestamp'] = pd.to_datetime(df['timestamp'])
53
 
54
- # Convert temperature from Celsius to Fahrenheit
55
- df['temperature'] = (df['temperature'] * 9/5) + 32
 
 
 
 
 
 
56
 
57
  return df, None
58
 
59
  except requests.exceptions.RequestException as e:
60
  return None, f"Error fetching data: {str(e)}"
61
 
62
- def create_plot(df):
63
  """
64
- Create an interactive plot using plotly
65
  """
66
- fig = px.line(df, x='timestamp', y='temperature',
67
- title='Temperature Over Time',
68
- labels={'timestamp': 'Time', 'temperature': 'Temperature (°F)'})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  return fig
70
 
71
  def fetch_and_display(station_id, hours):
@@ -75,17 +145,19 @@ def fetch_and_display(station_id, hours):
75
  df, error = get_weather_data(station_id, hours)
76
 
77
  if error:
78
- return None, error
79
 
80
  if df is not None and not df.empty:
81
- fig = create_plot(df)
82
- return fig, "Data fetched successfully!"
 
83
 
84
- return None, "No data available for the specified parameters."
85
 
86
  # Create Gradio interface
87
  with gr.Blocks() as demo:
88
  gr.Markdown("# Weather Data Viewer")
 
89
 
90
  with gr.Row():
91
  station_id = gr.Textbox(label="Station ID", value="YCTIM")
@@ -93,13 +165,17 @@ with gr.Blocks() as demo:
93
  label="Hours of Data", step=1)
94
 
95
  fetch_btn = gr.Button("Fetch Data")
96
- plot = gr.Plot()
 
 
 
 
97
  message = gr.Textbox(label="Status")
98
 
99
  fetch_btn.click(
100
  fn=fetch_and_display,
101
  inputs=[station_id, hours],
102
- outputs=[plot, message]
103
  )
104
 
105
  # Launch the app
 
2
  import gradio as gr
3
  import requests
4
  import pandas as pd
5
+ import numpy as np
6
  from datetime import datetime, timedelta
7
  import plotly.express as px
8
+ import plotly.graph_objects as go
9
+ from plotly.subplots import make_subplots
10
 
11
  def get_weather_data(station_id, hours=72):
12
  """
13
  Fetch weather data from NWS API
14
  """
 
15
  headers = {
16
  'User-Agent': '(Weather Data Fetcher, contact@yourdomain.com)',
17
  'Accept': 'application/json'
18
  }
19
 
 
20
  station_url = f'https://api.weather.gov/stations/{station_id}'
21
  try:
22
  response = requests.get(station_url, headers=headers)
23
  response.raise_for_status()
24
  station_data = response.json()
25
 
 
26
  observations_url = f'https://api.weather.gov/stations/{station_id}/observations'
27
  params = {
28
  'limit': hours,
 
34
 
35
  data = response.json()
36
 
 
37
  records = []
38
  for obs in data['features']:
39
  props = obs['properties']
 
43
  'relative_humidity': props['relativeHumidity']['value'],
44
  'wind_speed': props['windSpeed']['value'],
45
  'wind_direction': props['windDirection']['value'],
46
+ 'barometric_pressure': props['barometricPressure']['value'],
47
+ 'snow_depth': props.get('snowDepth', {}).get('value'),
48
+ 'snow_accumulation': props.get('snowfall', {}).get('value')
49
  }
50
  records.append(record)
51
 
52
  df = pd.DataFrame(records)
53
  df['timestamp'] = pd.to_datetime(df['timestamp'])
54
 
55
+ # Convert units to imperial
56
+ df['temperature'] = (df['temperature'] * 9/5) + 32 # C to F
57
+ df['wind_speed'] = df['wind_speed'] * 2.237 # m/s to mph
58
+ df['snow_depth'] = df['snow_depth'] * 39.3701 # meters to inches
59
+ df['snow_accumulation'] = df['snow_accumulation'] * 39.3701 # meters to inches
60
+
61
+ # Calculate cumulative snow accumulation
62
+ df['cumulative_snow'] = df['snow_accumulation'].fillna(0).cumsum()
63
 
64
  return df, None
65
 
66
  except requests.exceptions.RequestException as e:
67
  return None, f"Error fetching data: {str(e)}"
68
 
69
+ def create_plots(df):
70
  """
71
+ Create interactive plots using plotly
72
  """
73
+ # Create figure with secondary y-axis
74
+ fig = make_subplots(rows=3, cols=1,
75
+ subplot_titles=('Temperature Over Time',
76
+ 'Wind Speed Over Time',
77
+ 'Snow Accumulation Over Time'),
78
+ vertical_spacing=0.1,
79
+ heights=[0.33, 0.33, 0.33])
80
+
81
+ # Add temperature trace
82
+ fig.add_trace(
83
+ go.Scatter(x=df['timestamp'], y=df['temperature'],
84
+ name='Temperature', line=dict(color='red')),
85
+ row=1, col=1
86
+ )
87
+
88
+ # Add wind speed trace
89
+ fig.add_trace(
90
+ go.Scatter(x=df['timestamp'], y=df['wind_speed'],
91
+ name='Wind Speed', line=dict(color='blue')),
92
+ row=2, col=1
93
+ )
94
+
95
+ # Add snow accumulation trace
96
+ fig.add_trace(
97
+ go.Scatter(x=df['timestamp'], y=df['cumulative_snow'],
98
+ name='Cumulative Snow', line=dict(color='purple')),
99
+ row=3, col=1
100
+ )
101
+
102
+ # Update layout
103
+ fig.update_layout(
104
+ height=900,
105
+ showlegend=True,
106
+ title_text="Weather Conditions Over Time"
107
+ )
108
+
109
+ # Update axes labels
110
+ fig.update_yaxes(title_text="Temperature (°F)", row=1, col=1)
111
+ fig.update_yaxes(title_text="Wind Speed (mph)", row=2, col=1)
112
+ fig.update_yaxes(title_text="Snow Accumulation (inches)", row=3, col=1)
113
+ fig.update_xaxes(title_text="Time", row=3, col=1)
114
+
115
+ return fig
116
+
117
+ def create_wind_rose(df):
118
+ """
119
+ Create a wind rose diagram
120
+ """
121
+ # Create wind direction bins
122
+ direction_bins = np.arange(0, 361, 45)
123
+ df['direction_bin'] = pd.cut(df['wind_direction'],
124
+ bins=direction_bins,
125
+ labels=['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'])
126
+
127
+ # Calculate average wind speed for each direction
128
+ wind_stats = df.groupby('direction_bin')['wind_speed'].agg(['mean', 'count']).reset_index()
129
+
130
+ # Create wind rose
131
+ fig = px.bar_polar(wind_stats,
132
+ r="mean",
133
+ theta="direction_bin",
134
+ color="mean",
135
+ title="Wind Rose Diagram",
136
+ color_continuous_scale="blues")
137
+
138
+ fig.update_layout(height=400)
139
  return fig
140
 
141
  def fetch_and_display(station_id, hours):
 
145
  df, error = get_weather_data(station_id, hours)
146
 
147
  if error:
148
+ return None, None, error
149
 
150
  if df is not None and not df.empty:
151
+ time_series = create_plots(df)
152
+ wind_rose = create_wind_rose(df)
153
+ return time_series, wind_rose, "Data fetched successfully!"
154
 
155
+ return None, None, "No data available for the specified parameters."
156
 
157
  # Create Gradio interface
158
  with gr.Blocks() as demo:
159
  gr.Markdown("# Weather Data Viewer")
160
+ gr.Markdown("Displays temperature, wind speed, and snow accumulation data from NWS stations")
161
 
162
  with gr.Row():
163
  station_id = gr.Textbox(label="Station ID", value="YCTIM")
 
165
  label="Hours of Data", step=1)
166
 
167
  fetch_btn = gr.Button("Fetch Data")
168
+
169
+ with gr.Row():
170
+ time_series_plot = gr.Plot()
171
+ wind_rose_plot = gr.Plot()
172
+
173
  message = gr.Textbox(label="Status")
174
 
175
  fetch_btn.click(
176
  fn=fetch_and_display,
177
  inputs=[station_id, hours],
178
+ outputs=[time_series_plot, wind_rose_plot, message]
179
  )
180
 
181
  # Launch the app