Wajahat698 commited on
Commit
fccb8d7
·
verified ·
1 Parent(s): 16d359a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +136 -1
app.py CHANGED
@@ -207,6 +207,141 @@ def plot_model_results(results_df, average_value, title, model_type):
207
  logger.error("Error plotting model results: %s", e)
208
  raise
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  def plot_bucket_fullness(driver_df, title):
211
  # Determine required trust buckets
212
  buckets = [
@@ -657,7 +792,7 @@ def analyze_excel_single(file_path):
657
  results_df_nps = pd.read_csv(csv_output_path_nps)
658
  results_df_nps["Importance_percent"] = results_df_nps["Importance"] * 100
659
  average_value_nps = results_df_nps["Importance_percent"].mean()
660
- img_nps = plot_model_results(
661
  results_df_nps,
662
  average_value_nps,
663
  f"NPS Drivers: {file_name}",
 
207
  logger.error("Error plotting model results: %s", e)
208
  raise
209
 
210
+
211
+
212
+
213
+ def plot_model(results_df, average_value, title, model_type):
214
+ """
215
+ Plot model results with specific orders and colors for Trust and NPS models.
216
+ Args:
217
+ results_df (DataFrame): DataFrame containing predictor names and their importance.
218
+ average_value (float): Average importance value.
219
+ title (str): Title of the plot.
220
+ model_type (str): Type of model (either "Trust" or "NPS").
221
+ Returns:
222
+ Image: Image object containing the plot.
223
+ """
224
+
225
+ logger.info(
226
+ "Plotting model results for %s model with title '%s'.", model_type, title
227
+ )
228
+ try:
229
+ # Define color scheme
230
+ color_map = {
231
+ "Stability": "#375570",
232
+ "Development": "#E3B05B",
233
+ "Relationship": "#C63F48",
234
+ "Benefit": "#418387",
235
+ "Vision": "#DF8859",
236
+ "Competence": "#6D93AB",
237
+ "Trust": "#f5918a",
238
+ }
239
+
240
+ # Define the order for each model
241
+ if model_type == "Trust":
242
+ order = [
243
+ "Stability",
244
+ "Development",
245
+ "Relationship",
246
+ "Benefit",
247
+ "Vision",
248
+ "Competence",
249
+ ]
250
+ else: # "NPS"
251
+ order = [
252
+ "Trust",
253
+ "Stability",
254
+ "Development",
255
+ "Relationship",
256
+ "Benefit",
257
+ "Vision",
258
+ "Competence",
259
+ ]
260
+
261
+ # Apply the categorical ordering to the 'Predictor' column
262
+ results_df["Predictor"] = pd.Categorical(
263
+ results_df["Predictor"], categories=order, ordered=True
264
+ )
265
+ results_df.sort_values("Predictor", ascending=False, inplace=True)
266
+
267
+ # Create the figure and axis
268
+ fig, ax = plt.subplots(figsize=(10, 8))
269
+
270
+ # Set the x-axis labels with "%" using FuncFormatter
271
+ formatter = FuncFormatter(lambda x, _: f"{x:.0f}%")
272
+ ax.xaxis.set_major_formatter(formatter)
273
+
274
+ # Determine the dynamic range of the X-axis
275
+ actual_min = results_df["Importance_percent"].min()
276
+ actual_max = results_df["Importance_percent"].max()
277
+
278
+ # Calculate the x-axis limits
279
+ half_range = max(average_value - actual_min, actual_max - average_value)
280
+ x_min = 0 # start from zero
281
+ x_max = actual_max + 5 # a bit beyond max
282
+ plt.xlim(x_min, x_max)
283
+
284
+ # Set the x-axis ticks at every 5% interval and add dotted lines
285
+ x_ticks = np.arange(
286
+ np.floor(x_min), np.ceil(x_max) + 5, 5
287
+ ) # Ensures complete coverage
288
+ ax.set_xticks(x_ticks) # Set the ticks on the axis
289
+ for tick in x_ticks:
290
+ ax.axvline(
291
+ x=tick, color="grey", linestyle="--", linewidth=0.5, zorder=2
292
+ ) # Add dotted lines
293
+
294
+ # Create bars: all from 0 → value (left-to-right only)
295
+ for i, row in enumerate(results_df.itertuples(index=False)):
296
+ color = color_map[row.Predictor]
297
+
298
+ ax.barh(
299
+ row.Predictor,
300
+ row.Importance_percent,
301
+ left=0,
302
+ color=color,
303
+ edgecolor="white",
304
+ height=0.6,
305
+ zorder=3,
306
+ )
307
+
308
+ ax.text(
309
+ row.Importance_percent + 0.5,
310
+ i,
311
+ f"{row.Importance_percent:.1f}%",
312
+ va="center",
313
+ ha="left",
314
+ color="#8c8b8c",
315
+ )
316
+
317
+ # Draw the average line and set the title
318
+ ax.axvline(average_value, color="black", linewidth=1, linestyle="-", zorder=3)
319
+ plt.title(title, fontsize=14)
320
+
321
+ # Remove plot borders
322
+ ax.spines[["left", "top", "right"]].set_color("none")
323
+
324
+ # Change the colour of y-axis text
325
+ ax.tick_params(axis="y", colors="#8c8b8c", length=0)
326
+
327
+ # Send axes to background and tighten the layout
328
+ ax.set_axisbelow(True)
329
+ plt.tight_layout()
330
+
331
+ # Save the figure to a bytes buffer and then to an image
332
+ img_data = io.BytesIO()
333
+ plt.savefig(
334
+ img_data, format="png", facecolor=fig.get_facecolor(), edgecolor="none"
335
+ )
336
+ img_data.seek(0)
337
+ img = Image.open(img_data)
338
+ plt.close(fig)
339
+
340
+ return img
341
+
342
+ except Exception as e:
343
+ logger.error("Error plotting model results: %s", e)
344
+ raise
345
  def plot_bucket_fullness(driver_df, title):
346
  # Determine required trust buckets
347
  buckets = [
 
792
  results_df_nps = pd.read_csv(csv_output_path_nps)
793
  results_df_nps["Importance_percent"] = results_df_nps["Importance"] * 100
794
  average_value_nps = results_df_nps["Importance_percent"].mean()
795
+ img_nps = plot_model(
796
  results_df_nps,
797
  average_value_nps,
798
  f"NPS Drivers: {file_name}",