lyimo commited on
Commit
e96e967
·
verified ·
1 Parent(s): 7c43484

Update part2_visualization.py

Browse files
Files changed (1) hide show
  1. part2_visualization.py +129 -119
part2_visualization.py CHANGED
@@ -1,5 +1,3 @@
1
- # part2_visualization.py
2
-
3
  import plotly.graph_objects as go
4
  from plotly.subplots import make_subplots
5
  import folium
@@ -24,26 +22,36 @@ class VisualizationHandler:
24
  def create_interactive_plots(self, df):
25
  """Create enhanced interactive Plotly visualizations"""
26
  fig = make_subplots(
27
- rows=4, cols=1, # Added one more row for NDVI
28
  subplot_titles=(
29
  '<b>Temperature (°C)</b>',
30
  '<b>Humidity (%)</b>',
31
  '<b>Rainfall (mm/day)</b>',
32
- '<b>Vegetation Index (NDVI)</b>'
 
33
  ),
34
- vertical_spacing=0.08,
35
- row_heights=[0.25, 0.25, 0.25, 0.25]
36
  )
37
 
38
- # Add standard weather plots
39
- self.add_weather_plots(fig, df)
40
 
41
- # Add NDVI plot
 
 
 
 
 
 
42
  self.add_ndvi_plot(fig, df)
43
 
 
 
 
44
  # Update layout
45
  fig.update_layout(
46
- height=1000, # Increased height for additional plot
47
  showlegend=True,
48
  title={
49
  'text': "Enhanced Tobacco Growing Conditions Analysis",
@@ -71,55 +79,58 @@ class VisualizationHandler:
71
 
72
  return fig
73
 
74
- def add_weather_plots(self, fig, df):
75
- """Add weather-related plots"""
76
- # Temperature plot
77
- for data_type, color in [('historical', 'royalblue'),
78
- ('forecast_5day', 'firebrick'),
79
- ('forecast_extended', 'rgba(255, 165, 0, 0.5)')]:
80
- mask = df['type'] == data_type
81
- if any(mask):
82
- fig.add_trace(
83
- go.Scatter(
84
- x=df[mask]['date'],
85
- y=df[mask]['temperature'],
86
- name=f'{data_type.replace("_", " ").title()} Temperature',
87
- line=dict(color=color, width=2),
88
- mode='lines'
89
- ),
90
- row=1, col=1
91
- )
92
-
93
- # Add temperature rolling average
94
  fig.add_trace(
95
  go.Scatter(
96
  x=df['date'],
97
- y=df['temp_7day_avg'],
98
- name='7-day Temperature Average',
99
- line=dict(color='purple', width=1, dash='dot'),
100
- mode='lines'
 
 
101
  ),
102
  row=1, col=1
103
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
- # Humidity plot
106
- for data_type, color in [('historical', 'royalblue'),
107
- ('forecast_5day', 'firebrick'),
108
- ('forecast_extended', 'rgba(255, 165, 0, 0.5)')]:
109
- mask = df['type'] == data_type
110
- if any(mask):
111
- fig.add_trace(
112
- go.Scatter(
113
- x=df[mask]['date'],
114
- y=df[mask]['humidity'],
115
- name=f'{data_type.replace("_", " ").title()} Humidity',
116
- line=dict(color=color, width=2),
117
- mode='lines'
118
- ),
119
- row=2, col=1
120
- )
121
-
122
- # Add humidity rolling average
123
  fig.add_trace(
124
  go.Scatter(
125
  x=df['date'],
@@ -131,67 +142,75 @@ class VisualizationHandler:
131
  row=2, col=1
132
  )
133
 
134
- # Rainfall plot
135
- for data_type, color in [('historical', 'royalblue'),
136
- ('forecast_5day', 'firebrick'),
137
- ('forecast_extended', 'rgba(255, 165, 0, 0.5)')]:
138
- mask = df['type'] == data_type
139
- if any(mask):
140
- fig.add_trace(
141
- go.Bar(
142
- x=df[mask]['date'],
143
- y=df[mask]['rainfall'],
144
- name=f'{data_type.replace("_", " ").title()} Rainfall',
145
- marker_color=color
146
- ),
147
- row=3, col=1
148
- )
 
 
 
 
 
 
 
149
 
150
  def add_ndvi_plot(self, fig, df):
151
- """Add NDVI plot"""
152
- # Historical NDVI
153
- mask = df['type'] == 'historical'
154
- if any(mask):
155
- fig.add_trace(
156
- go.Scatter(
157
- x=df[mask]['date'],
158
- y=df[mask]['estimated_ndvi'],
159
- name='Historical NDVI',
160
- line=dict(color='green', width=2),
161
- mode='lines'
162
- ),
163
- row=4, col=1
164
- )
165
-
166
- # Forecast NDVI
167
- mask = df['type'].isin(['forecast_5day', 'forecast_extended'])
168
- if any(mask):
169
- fig.add_trace(
170
- go.Scatter(
171
- x=df[mask]['date'],
172
- y=df[mask]['estimated_ndvi'],
173
- name='Forecast NDVI',
174
- line=dict(color='orange', width=2, dash='dot'),
175
- mode='lines'
176
- ),
177
  row=4, col=1
178
  )
179
 
180
- # Add optimal NDVI range
181
- fig.add_hline(y=self.optimal_conditions['ndvi']['min'],
182
- line_dash="dash", line_color="green",
183
- annotation_text="Min Optimal NDVI",
184
- row=4, col=1)
185
- fig.add_hline(y=self.optimal_conditions['ndvi']['max'],
186
- line_dash="dash", line_color="green",
187
- annotation_text="Max Optimal NDVI",
188
- row=4, col=1)
 
 
 
 
189
 
190
  def create_enhanced_map(self, lat, lon, score, ndvi_value):
191
  """Create an interactive map with both weather and vegetation analysis"""
192
  m = folium.Map(location=[lat, lon], zoom_start=13)
193
 
194
- # Add base marker
 
 
 
 
195
  folium.Marker(
196
  [lat, lon],
197
  popup='Analysis Location',
@@ -206,43 +225,34 @@ class VisualizationHandler:
206
  caption='NDVI Values'
207
  )
208
 
209
- # Add NDVI-based circle
210
- ndvi_color = ndvi_colormap(ndvi_value)
211
  folium.Circle(
212
  radius=2000,
213
  location=[lat, lon],
214
  popup=f'NDVI: {ndvi_value:.2f}',
215
- color=ndvi_color,
216
  fill=True,
217
  fillOpacity=0.4
218
  ).add_to(m)
219
 
220
- # Add score-based circles
221
  score_color = self.get_score_color(score)
222
  for radius in [500, 1000, 1500]:
223
  folium.Circle(
224
  radius=radius,
225
  location=[lat, lon],
 
226
  color=score_color,
227
- popup=f'Growing Score: {score:.2f}',
228
  fill=False,
229
  weight=2
230
  ).add_to(m)
231
 
232
- # Add measurement tools
233
- plugins.MeasureControl(position='topright').add_to(m)
234
-
235
- # Add fullscreen option
236
- plugins.Fullscreen().add_to(m)
237
-
238
  # Add mini map
239
  minimap = plugins.MiniMap()
240
  m.add_child(minimap)
241
 
242
- # Add layer control
243
  folium.LayerControl().add_to(m)
244
-
245
- # Add colormap to map
246
  m.add_child(ndvi_colormap)
247
 
248
  return m._repr_html_()
@@ -257,14 +267,14 @@ class VisualizationHandler:
257
  return 'orange'
258
  return 'red'
259
 
260
- def create_gauge_chart(self, score):
261
  """Create an enhanced gauge chart for the overall score"""
262
  fig = go.Figure(go.Indicator(
263
  mode="gauge+number+delta",
264
  value=score,
265
  domain={'x': [0, 1], 'y': [0, 1]},
266
  title={
267
- 'text': "Growing Conditions Score",
268
  'font': {'size': 24}
269
  },
270
  delta={
 
 
 
1
  import plotly.graph_objects as go
2
  from plotly.subplots import make_subplots
3
  import folium
 
22
  def create_interactive_plots(self, df):
23
  """Create enhanced interactive Plotly visualizations"""
24
  fig = make_subplots(
25
+ rows=5, cols=1, # Added rows for NDVI and Daily Suitability
26
  subplot_titles=(
27
  '<b>Temperature (°C)</b>',
28
  '<b>Humidity (%)</b>',
29
  '<b>Rainfall (mm/day)</b>',
30
+ '<b>Vegetation Index (NDVI)</b>',
31
+ '<b>Daily Growing Suitability</b>'
32
  ),
33
+ vertical_spacing=0.07,
34
+ row_heights=[0.2, 0.2, 0.2, 0.2, 0.2]
35
  )
36
 
37
+ # Temperature plot
38
+ self.add_temperature_plot(fig, df)
39
 
40
+ # Humidity plot
41
+ self.add_humidity_plot(fig, df)
42
+
43
+ # Rainfall plot
44
+ self.add_rainfall_plot(fig, df)
45
+
46
+ # NDVI plot
47
  self.add_ndvi_plot(fig, df)
48
 
49
+ # Daily Suitability plot
50
+ self.add_suitability_plot(fig, df)
51
+
52
  # Update layout
53
  fig.update_layout(
54
+ height=1200,
55
  showlegend=True,
56
  title={
57
  'text': "Enhanced Tobacco Growing Conditions Analysis",
 
79
 
80
  return fig
81
 
82
+ def add_temperature_plot(self, fig, df):
83
+ """Add temperature visualization"""
84
+ # Add detailed temperature data
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  fig.add_trace(
86
  go.Scatter(
87
  x=df['date'],
88
+ y=df['temp_max'],
89
+ name='Max Temperature',
90
+ line=dict(color='red', width=1),
91
+ mode='lines',
92
+ fillcolor='rgba(255,0,0,0.1)',
93
+ fill='tonexty'
94
  ),
95
  row=1, col=1
96
  )
97
+
98
+ fig.add_trace(
99
+ go.Scatter(
100
+ x=df['date'],
101
+ y=df['temp_min'],
102
+ name='Min Temperature',
103
+ line=dict(color='blue', width=1),
104
+ mode='lines',
105
+ fillcolor='rgba(0,0,255,0.1)',
106
+ fill='tonexty'
107
+ ),
108
+ row=1, col=1
109
+ )
110
+
111
+ # Add optimal range
112
+ for limit in ['min', 'max']:
113
+ fig.add_hline(
114
+ y=self.optimal_conditions['temperature'][limit],
115
+ line_dash="dash",
116
+ line_color="green",
117
+ annotation_text=f"Optimal {limit}",
118
+ row=1, col=1
119
+ )
120
 
121
+ def add_humidity_plot(self, fig, df):
122
+ """Add humidity visualization"""
123
+ fig.add_trace(
124
+ go.Scatter(
125
+ x=df['date'],
126
+ y=df['humidity'],
127
+ name='Humidity',
128
+ line=dict(color='blue', width=2),
129
+ mode='lines'
130
+ ),
131
+ row=2, col=1
132
+ )
133
+
 
 
 
 
 
134
  fig.add_trace(
135
  go.Scatter(
136
  x=df['date'],
 
142
  row=2, col=1
143
  )
144
 
145
+ def add_rainfall_plot(self, fig, df):
146
+ """Add rainfall visualization"""
147
+ fig.add_trace(
148
+ go.Bar(
149
+ x=df['date'],
150
+ y=df['rainfall'],
151
+ name='Rainfall',
152
+ marker_color='blue'
153
+ ),
154
+ row=3, col=1
155
+ )
156
+
157
+ fig.add_trace(
158
+ go.Scatter(
159
+ x=df['date'],
160
+ y=df['rainfall_7day_avg'],
161
+ name='7-day Rainfall Average',
162
+ line=dict(color='purple', width=1, dash='dot'),
163
+ mode='lines'
164
+ ),
165
+ row=3, col=1
166
+ )
167
 
168
  def add_ndvi_plot(self, fig, df):
169
+ """Add NDVI visualization"""
170
+ fig.add_trace(
171
+ go.Scatter(
172
+ x=df['date'],
173
+ y=df['estimated_ndvi'],
174
+ name='Vegetation Index',
175
+ line=dict(color='green', width=2),
176
+ mode='lines'
177
+ ),
178
+ row=4, col=1
179
+ )
180
+
181
+ # Add optimal NDVI range
182
+ for limit in ['min', 'max']:
183
+ fig.add_hline(
184
+ y=self.optimal_conditions['ndvi'][limit],
185
+ line_dash="dash",
186
+ line_color="green",
187
+ annotation_text=f"Optimal {limit}",
 
 
 
 
 
 
 
188
  row=4, col=1
189
  )
190
 
191
+ def add_suitability_plot(self, fig, df):
192
+ """Add daily suitability visualization"""
193
+ fig.add_trace(
194
+ go.Scatter(
195
+ x=df['date'],
196
+ y=df['daily_suitability'],
197
+ name='Growing Suitability',
198
+ line=dict(color='darkblue', width=2),
199
+ mode='lines',
200
+ fill='tozeroy'
201
+ ),
202
+ row=5, col=1
203
+ )
204
 
205
  def create_enhanced_map(self, lat, lon, score, ndvi_value):
206
  """Create an interactive map with both weather and vegetation analysis"""
207
  m = folium.Map(location=[lat, lon], zoom_start=13)
208
 
209
+ # Add measurement tools
210
+ plugins.MeasureControl(position='topright').add_to(m)
211
+ plugins.Fullscreen().add_to(m)
212
+
213
+ # Add location marker
214
  folium.Marker(
215
  [lat, lon],
216
  popup='Analysis Location',
 
225
  caption='NDVI Values'
226
  )
227
 
228
+ # Add NDVI circle
 
229
  folium.Circle(
230
  radius=2000,
231
  location=[lat, lon],
232
  popup=f'NDVI: {ndvi_value:.2f}',
233
+ color=ndvi_colormap(ndvi_value),
234
  fill=True,
235
  fillOpacity=0.4
236
  ).add_to(m)
237
 
238
+ # Add growing suitability circles
239
  score_color = self.get_score_color(score)
240
  for radius in [500, 1000, 1500]:
241
  folium.Circle(
242
  radius=radius,
243
  location=[lat, lon],
244
+ popup=f'Suitability Score: {score:.2f}',
245
  color=score_color,
 
246
  fill=False,
247
  weight=2
248
  ).add_to(m)
249
 
 
 
 
 
 
 
250
  # Add mini map
251
  minimap = plugins.MiniMap()
252
  m.add_child(minimap)
253
 
254
+ # Add layer control and colormap
255
  folium.LayerControl().add_to(m)
 
 
256
  m.add_child(ndvi_colormap)
257
 
258
  return m._repr_html_()
 
267
  return 'orange'
268
  return 'red'
269
 
270
+ def create_gauge_chart(self, score, title="Growing Conditions Score"):
271
  """Create an enhanced gauge chart for the overall score"""
272
  fig = go.Figure(go.Indicator(
273
  mode="gauge+number+delta",
274
  value=score,
275
  domain={'x': [0, 1], 'y': [0, 1]},
276
  title={
277
+ 'text': title,
278
  'font': {'size': 24}
279
  },
280
  delta={