9
9
from statsmodels .tsa .holtwinters import ExponentialSmoothing
10
10
11
11
# Configuration constants
12
- PREDICTED_DATE = "27-Nov -24"
12
+ PREDICTED_DATE = "18-Dec -24"
13
13
FILE_PATH = "results.csv"
14
14
15
15
def load_and_prepare_data (file_path ) -> tuple :
@@ -122,9 +122,30 @@ def calculate_cyclical_adjustments(data: list) -> float:
122
122
forecast = ex_model .forecast (steps = 1 )
123
123
return forecast .iloc [0 ]
124
124
125
+ # function to add value labels
126
+ def plot_labels (x , y , color ):
127
+ """
128
+ Add value labels to plot points with proper formatting and positioning
129
+
130
+ Parameters:
131
+ x: x-coordinates (dates)
132
+ y: y-coordinates (values)
133
+ color: label color (string)
134
+ """
135
+ for i in range (len (x )):
136
+ # Format large numbers with commas
137
+ label = f'{ int (y [i ]):,} '
138
+ plt .annotate (label ,
139
+ (x [i ], y [i ]),
140
+ textcoords = "offset points" ,
141
+ xytext = (0 , 10 ), # 10 points vertical offset
142
+ ha = 'center' , # horizontal alignment
143
+ va = 'bottom' , # vertical alignment
144
+ color = color ) # color
145
+
125
146
def plot_results (result_df : DataFrame , next_date : datetime , next_value_weighted_avg : float , next_value_linear : float , cyclical_adjustment : float ) -> None :
126
147
"""
127
- Create and display visualization of results
148
+ Create and display visualization of results with improved layout and labels
128
149
129
150
Parameter:
130
151
result_df (DataFrame): Results data
@@ -133,29 +154,52 @@ def plot_results(result_df: DataFrame, next_date: datetime, next_value_weighted_
133
154
next_value_linear (float): Linear trend prediction
134
155
cyclical_adjustment (float): Cyclical adjustment prediction
135
156
"""
136
- plt .figure (figsize = (10 , 6 ))
137
- plt .plot (result_df ['ADate' ], result_df ['Actual' ], color = 'purple' , label = 'Actual' , marker = 'o' )
157
+ # Create figure with larger size and adjusted margins
158
+ plt .figure (figsize = (15 , 8 ))
159
+
160
+ # Add more padding to the bottom and right
161
+ plt .subplots_adjust (bottom = 0.2 , right = 0.95 )
162
+
163
+ # Plot the actual values
164
+ plt .plot (result_df ['ADate' ], result_df ['Actual' ],
165
+ color = 'purple' , label = 'Actual' , marker = 'o' )
138
166
plt .plot (result_df ['PDate' ], result_df ['Predicted_LinearTrend' ], color = 'pink' ,
139
167
label = 'Predicted (Linear Trend)' , linestyle = '-.' , marker = '^' )
140
168
plt .plot (result_df ['PDate' ], result_df ['Predicted_CyclicalAdjustment' ], color = 'green' ,
141
- label = 'Predicted (Cyclical Adjustment)' , linestyle = '--' , marker = '*' )
169
+ label = 'Predicted (Cyclical Adjustment)' , linestyle = '--' , marker = '*' )
170
+
171
+ # Add value labels to the points
172
+ plot_labels (result_df ['ADate' ], result_df ['Actual' ], 'purple' )
173
+ plot_labels (result_df ['PDate' ], result_df ['Predicted_CyclicalAdjustment' ], 'green' )
142
174
143
175
plt .xlabel ('Date' )
144
176
plt .ylabel ('Value' )
145
177
plt .title ('Actual and Value Prediction' )
146
- plt .legend ()
178
+
179
+ # Specify legend location explicitly instead of using 'best'
180
+ plt .legend (loc = 'upper left' , bbox_to_anchor = (0.02 , 0.98 ))
181
+
147
182
plt .grid (True )
148
- plt .xticks (rotation = 45 )
149
- plt .tight_layout ()
150
183
151
- # Annotate predictions
184
+ # Rotate x-axis labels for better readability
185
+ plt .xticks (rotation = 45 , ha = 'right' )
186
+
187
+ # Add the prediction line and label
152
188
plt .axvline (x = next_date , color = 'red' , linestyle = '--' )
153
- plt .annotate (f'{ int (next_value_weighted_avg ):,} ' , (next_date , next_value_weighted_avg ),
154
- textcoords = "offset points" , xytext = (0 , 10 ), ha = 'center' , color = 'purple' )
189
+ """plt.annotate(f'{int(next_value_weighted_avg):,}',
190
+ (next_date, next_value_weighted_avg),
191
+ textcoords="offset points",
192
+ xytext=(0, 10),
193
+ ha='center',
194
+ color='purple')
195
+ """
155
196
plt .annotate (f'{ int (next_value_linear [0 ]):,} ' , (next_date , next_value_linear ),
156
- textcoords = "offset points" , xytext = (0 , - 20 ), ha = 'center' , color = 'pink' )
157
- plt .annotate (f'{ int (cyclical_adjustment ):,} ' , (next_date , cyclical_adjustment ),
158
- textcoords = "offset points" , xytext = (0 , 20 ), ha = 'center' , color = 'green' )
197
+ textcoords = "offset points" , xytext = (0 , - 20 ), ha = 'center' , color = 'pink' )
198
+ #plt.annotate(f'{int(cyclical_adjustment):,}', (next_date, cyclical_adjustment),
199
+ # textcoords="offset points", xytext=(0, 20), ha='center', color='green')
200
+
201
+ # Ensure everything fits within the figure bounds
202
+ plt .tight_layout ()
159
203
plt .show ()
160
204
161
205
def print_predictions (next_date , next_value , next_value_linear , cyclical_adjustment , next_value_weighted_avg ) -> None :
@@ -179,12 +223,6 @@ def main() -> None:
179
223
Main function to for the prediction process
180
224
"""
181
225
182
- # Model weights
183
- weight_naive_bayes = 0.99973895177364354734851780911949
184
- weight_cyclical_patterns = 9844365 #cyclical_adjustment
185
- weight_linear_offset = 42900
186
- weight_cyclical = 0.1
187
-
188
226
# Load and prepare data
189
227
df , X , y = load_and_prepare_data (FILE_PATH )
190
228
@@ -206,19 +244,16 @@ def main() -> None:
206
244
data_for_cyclical_adjustment = list (zip (df ['Date' ], df ['Numbers' ]))
207
245
cyclical_adjustment = calculate_cyclical_adjustments (data_for_cyclical_adjustment )
208
246
209
- """
247
+ # Model weights
248
+ weight_naive_bayes = 0.99795541336866801512165950581255 # adjust
249
+ weight_linear_offset = 1589 # adjust
250
+
210
251
# Calculate weighted average prediction
211
252
next_value_weighted_avg = (
212
253
weight_naive_bayes * cyclical_adjustment +
213
254
weight_linear_offset +
214
255
slope * next_value_linear [0 ]
215
256
)
216
- """
217
- # Calculate Weighted Average prediction
218
- next_value_weighted_avg = (
219
- weight_naive_bayes * weight_cyclical_patterns + weight_linear_offset + # next_value[0] +
220
- slope * next_value_linear [0 ]
221
- )
222
257
223
258
# Prepare results DataFrame
224
259
predicted_date_list = list (pd .to_datetime (df ['Date' ], format = '%d-%b-%y' )) + [next_date ]
0 commit comments