lyimo commited on
Commit
0829f5d
·
verified ·
1 Parent(s): e31ae34

Create part2_visualization.py

Browse files
Files changed (1) hide show
  1. part2_visualization.py +246 -0
part2_visualization.py ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # part2_visualization.py
2
+
3
+ import plotly.graph_objects as go
4
+ from plotly.subplots import make_subplots
5
+ import folium
6
+ import numpy as np
7
+
8
+ class VisualizationHandler:
9
+ def __init__(self, optimal_conditions):
10
+ self.optimal_conditions = optimal_conditions
11
+
12
+ def create_interactive_plots(self, df):
13
+ """Create enhanced interactive Plotly visualizations"""
14
+ fig = make_subplots(
15
+ rows=3, cols=1,
16
+ subplot_titles=(
17
+ '<b>Temperature (°C)</b>',
18
+ '<b>Humidity (%)</b>',
19
+ '<b>Rainfall (mm/day)</b>'
20
+ ),
21
+ vertical_spacing=0.12,
22
+ row_heights=[0.33, 0.33, 0.33]
23
+ )
24
+
25
+ # Temperature plot with forecast types
26
+ for data_type, color in [('historical', 'royalblue'),
27
+ ('forecast_5day', 'firebrick'),
28
+ ('forecast_extended', 'rgba(255, 165, 0, 0.5)')]:
29
+ mask = df['type'] == data_type
30
+ if any(mask):
31
+ fig.add_trace(
32
+ go.Scatter(
33
+ x=df[mask]['date'],
34
+ y=df[mask]['temperature'],
35
+ name=f'{data_type.replace("_", " ").title()} Temperature',
36
+ line=dict(color=color, width=2),
37
+ mode='lines'
38
+ ),
39
+ row=1, col=1
40
+ )
41
+
42
+ # Add temperature rolling average
43
+ fig.add_trace(
44
+ go.Scatter(
45
+ x=df['date'],
46
+ y=df['temp_7day_avg'],
47
+ name='7-day Temperature Average',
48
+ line=dict(color='purple', width=1, dash='dot'),
49
+ mode='lines'
50
+ ),
51
+ row=1, col=1
52
+ )
53
+
54
+ # Humidity plot with forecast types
55
+ for data_type, color in [('historical', 'royalblue'),
56
+ ('forecast_5day', 'firebrick'),
57
+ ('forecast_extended', 'rgba(255, 165, 0, 0.5)')]:
58
+ mask = df['type'] == data_type
59
+ if any(mask):
60
+ fig.add_trace(
61
+ go.Scatter(
62
+ x=df[mask]['date'],
63
+ y=df[mask]['humidity'],
64
+ name=f'{data_type.replace("_", " ").title()} Humidity',
65
+ line=dict(color=color, width=2),
66
+ mode='lines'
67
+ ),
68
+ row=2, col=1
69
+ )
70
+
71
+ # Add humidity rolling average
72
+ fig.add_trace(
73
+ go.Scatter(
74
+ x=df['date'],
75
+ y=df['humidity_7day_avg'],
76
+ name='7-day Humidity Average',
77
+ line=dict(color='purple', width=1, dash='dot'),
78
+ mode='lines'
79
+ ),
80
+ row=2, col=1
81
+ )
82
+
83
+ # Rainfall plot with forecast types
84
+ for data_type, color in [('historical', 'royalblue'),
85
+ ('forecast_5day', 'firebrick'),
86
+ ('forecast_extended', 'rgba(255, 165, 0, 0.5)')]:
87
+ mask = df['type'] == data_type
88
+ if any(mask):
89
+ fig.add_trace(
90
+ go.Bar(
91
+ x=df[mask]['date'],
92
+ y=df[mask]['rainfall'],
93
+ name=f'{data_type.replace("_", " ").title()} Rainfall',
94
+ marker_color=color
95
+ ),
96
+ row=3, col=1
97
+ )
98
+
99
+ # Add optimal ranges
100
+ for row, (param, limits) in enumerate([
101
+ ('temperature', self.optimal_conditions['temperature']),
102
+ ('humidity', self.optimal_conditions['humidity']),
103
+ ('rainfall', self.optimal_conditions['rainfall'])
104
+ ], 1):
105
+ fig.add_hline(y=limits['min'], line_dash="dash", line_color="green",
106
+ annotation_text="Min Optimal", row=row, col=1)
107
+ fig.add_hline(y=limits['max'], line_dash="dash", line_color="green",
108
+ annotation_text="Max Optimal", row=row, col=1)
109
+
110
+ # Add seasonal indicators
111
+ seasons = df['season'].unique()
112
+ season_colors = {
113
+ 'Spring': 'rgba(0,255,0,0.1)',
114
+ 'Summer': 'rgba(255,255,0,0.1)',
115
+ 'Fall': 'rgba(255,165,0,0.1)',
116
+ 'Winter': 'rgba(0,0,255,0.1)'
117
+ }
118
+
119
+ for season in seasons:
120
+ season_data = df[df['season'] == season]
121
+ if not season_data.empty:
122
+ fig.add_vrect(
123
+ x0=season_data['date'].iloc[0],
124
+ x1=season_data['date'].iloc[-1],
125
+ fillcolor=season_colors[season],
126
+ layer="below",
127
+ line_width=0,
128
+ row="all"
129
+ )
130
+
131
+ # Update layout
132
+ fig.update_layout(
133
+ height=800,
134
+ showlegend=True,
135
+ title={
136
+ 'text': "Enhanced Tobacco Growing Conditions Analysis",
137
+ 'y':0.95,
138
+ 'x':0.5,
139
+ 'xanchor': 'center',
140
+ 'yanchor': 'top',
141
+ 'font': dict(size=20)
142
+ },
143
+ paper_bgcolor='white',
144
+ plot_bgcolor='rgba(0,0,0,0.05)',
145
+ font=dict(size=12),
146
+ legend=dict(
147
+ orientation="h",
148
+ yanchor="bottom",
149
+ y=1.02,
150
+ xanchor="right",
151
+ x=1
152
+ ),
153
+ margin=dict(l=60, r=30, t=100, b=60)
154
+ )
155
+
156
+ fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,0,0.1)')
157
+ fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,0,0.1)')
158
+
159
+ return fig
160
+
161
+ def create_map(self, lat, lon, score):
162
+ """Create an interactive map with growing suitability overlay"""
163
+ m = folium.Map(location=[lat, lon], zoom_start=10)
164
+
165
+ # Add location marker
166
+ folium.Marker(
167
+ [lat, lon],
168
+ popup='Analysis Location',
169
+ icon=folium.Icon(color='red', icon='info-sign')
170
+ ).add_to(m)
171
+
172
+ # Color based on score
173
+ if score >= 0.8:
174
+ color = 'green'
175
+ elif score >= 0.6:
176
+ color = 'yellow'
177
+ elif score >= 0.4:
178
+ color = 'orange'
179
+ else:
180
+ color = 'red'
181
+
182
+ # Add analysis zones
183
+ folium.Circle(
184
+ radius=5000,
185
+ location=[lat, lon],
186
+ popup=f'Growing Suitability Score: {score:.2f}',
187
+ color=color,
188
+ fill=True,
189
+ fillOpacity=0.4
190
+ ).add_to(m)
191
+
192
+ # Add smaller analysis zones
193
+ for radius in [2000, 3500]:
194
+ folium.Circle(
195
+ radius=radius,
196
+ location=[lat, lon],
197
+ color=color,
198
+ fill=False,
199
+ weight=1
200
+ ).add_to(m)
201
+
202
+ return m._repr_html_()
203
+
204
+ def create_gauge_chart(self, score):
205
+ """Create an enhanced gauge chart for the overall score"""
206
+ fig = go.Figure(go.Indicator(
207
+ mode="gauge+number+delta",
208
+ value=score,
209
+ domain={'x': [0, 1], 'y': [0, 1]},
210
+ title={
211
+ 'text': "Growing Conditions Score",
212
+ 'font': {'size': 24}
213
+ },
214
+ delta={
215
+ 'reference': 0.8,
216
+ 'increasing': {'color': "green"},
217
+ 'decreasing': {'color': "red"}
218
+ },
219
+ gauge={
220
+ 'axis': {'range': [None, 1], 'tickwidth': 1, 'tickcolor': "darkblue"},
221
+ 'bar': {'color': "darkblue"},
222
+ 'bgcolor': "white",
223
+ 'borderwidth': 2,
224
+ 'bordercolor': "gray",
225
+ 'steps': [
226
+ {'range': [0, 0.4], 'color': 'rgba(255, 0, 0, 0.6)'},
227
+ {'range': [0.4, 0.6], 'color': 'rgba(255, 255, 0, 0.6)'},
228
+ {'range': [0.6, 0.8], 'color': 'rgba(144, 238, 144, 0.6)'},
229
+ {'range': [0.8, 1], 'color': 'rgba(0, 128, 0, 0.6)'}
230
+ ],
231
+ 'threshold': {
232
+ 'line': {'color': "red", 'width': 4},
233
+ 'thickness': 0.75,
234
+ 'value': 0.8
235
+ }
236
+ }
237
+ ))
238
+
239
+ fig.update_layout(
240
+ height=300,
241
+ margin=dict(l=20, r=20, t=60, b=20),
242
+ paper_bgcolor="white",
243
+ font={'color': "darkblue", 'family': "Arial"}
244
+ )
245
+
246
+ return fig