Spaces:
Running
Running
Update analytics_plot_generator.py
Browse files- analytics_plot_generator.py +21 -23
analytics_plot_generator.py
CHANGED
@@ -16,7 +16,7 @@ def create_placeholder_plot(title="No Data or Plot Error", message="Data might b
|
|
16 |
fig, ax = plt.subplots(figsize=(8, 4))
|
17 |
ax.text(0.5, 0.5, f"{title}\n{message}", ha='center', va='center', fontsize=10, wrap=True)
|
18 |
ax.axis('off')
|
19 |
-
|
20 |
# Add spacing for consistency, though it might be less critical for placeholders
|
21 |
fig.subplots_adjust(top=0.90)
|
22 |
return fig
|
@@ -26,6 +26,7 @@ def create_placeholder_plot(title="No Data or Plot Error", message="Data might b
|
|
26 |
fig_err, ax_err = plt.subplots()
|
27 |
ax_err.text(0.5, 0.5, "Fatal: Plot generation error", ha='center', va='center')
|
28 |
ax_err.axis('off')
|
|
|
29 |
fig_err.subplots_adjust(top=0.90)
|
30 |
return fig_err
|
31 |
# No plt.close(fig) here as Gradio handles the figure object.
|
@@ -64,7 +65,7 @@ def generate_posts_activity_plot(df, date_column='published_at'):
|
|
64 |
ax.set_ylabel('Number of Posts')
|
65 |
ax.grid(True, linestyle='--', alpha=0.7)
|
66 |
plt.xticks(rotation=45)
|
67 |
-
|
68 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
69 |
logging.info("Successfully generated posts activity plot.")
|
70 |
return fig
|
@@ -73,10 +74,7 @@ def generate_posts_activity_plot(df, date_column='published_at'):
|
|
73 |
if fig: plt.close(fig) # Close if fig was created before error
|
74 |
return create_placeholder_plot(title="Posts Activity Error", message=str(e))
|
75 |
finally:
|
76 |
-
|
77 |
-
# However, if fig is returned, Gradio handles it.
|
78 |
-
# The plt.close('all') was too broad. We only close specific figures if not returned.
|
79 |
-
pass # Let Gradio handle the returned figure. If a placeholder is returned, its figure is handled there.
|
80 |
|
81 |
|
82 |
def generate_engagement_type_plot(df, likes_col='likeCount', comments_col='commentCount', shares_col='shareCount'):
|
@@ -125,7 +123,7 @@ def generate_engagement_type_plot(df, likes_col='likeCount', comments_col='comme
|
|
125 |
yval = bar.get_height()
|
126 |
ax.text(bar.get_x() + bar.get_width()/2.0, yval + (0.01 * max(engagement_data.values(), default=10)), str(int(yval)), ha='center', va='bottom')
|
127 |
|
128 |
-
|
129 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
130 |
logging.info("Successfully generated engagement type plot.")
|
131 |
return fig
|
@@ -170,7 +168,7 @@ def generate_mentions_activity_plot(df, date_column='date'):
|
|
170 |
ax.set_ylabel('Number of Mentions')
|
171 |
ax.grid(True, linestyle='--', alpha=0.7)
|
172 |
plt.xticks(rotation=45)
|
173 |
-
|
174 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
175 |
logging.info("Successfully generated mentions activity plot.")
|
176 |
return fig
|
@@ -207,7 +205,7 @@ def generate_mention_sentiment_plot(df, sentiment_column='sentiment_label'):
|
|
207 |
ax.pie(sentiment_counts, labels=sentiment_counts.index, autopct='%1.1f%%', startangle=90, colors=pie_colors)
|
208 |
ax.set_title('Mention Sentiment Distribution', y=1.03) # Matplotlib title
|
209 |
ax.axis('equal')
|
210 |
-
|
211 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
212 |
logging.info("Successfully generated mention sentiment plot.")
|
213 |
return fig
|
@@ -261,7 +259,7 @@ def generate_followers_count_over_time_plot(df, date_info_column='category_name'
|
|
261 |
ax.legend()
|
262 |
ax.grid(True, linestyle='--', alpha=0.7)
|
263 |
plt.xticks(rotation=45)
|
264 |
-
|
265 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
266 |
return fig
|
267 |
except Exception as e:
|
@@ -327,7 +325,7 @@ def generate_followers_growth_rate_plot(df, date_info_column='category_name',
|
|
327 |
ax.legend()
|
328 |
ax.grid(True, linestyle='--', alpha=0.7)
|
329 |
plt.xticks(rotation=45)
|
330 |
-
|
331 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
332 |
return fig
|
333 |
except Exception as e:
|
@@ -400,7 +398,7 @@ def generate_followers_by_demographics_plot(df, category_col='category_name',
|
|
400 |
ax.text(bar_item.get_x() + bar_item.get_width()/2.0, yval + (0.01 * ax.get_ylim()[1]),
|
401 |
str(int(yval)), ha='center', va='bottom', fontsize=8)
|
402 |
|
403 |
-
|
404 |
fig.subplots_adjust(top=0.85) # Adjust top for more space, especially with rotated labels
|
405 |
return fig
|
406 |
except Exception as e:
|
@@ -453,7 +451,7 @@ def generate_engagement_rate_over_time_plot(df, date_column='published_at', enga
|
|
453 |
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=formatter_xmax))
|
454 |
ax.grid(True, linestyle='--', alpha=0.7)
|
455 |
plt.xticks(rotation=45)
|
456 |
-
|
457 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
458 |
return fig
|
459 |
except Exception as e:
|
@@ -494,7 +492,7 @@ def generate_reach_over_time_plot(df, date_column='published_at', reach_col='cli
|
|
494 |
ax.set_ylabel('Total Clicks') # Label consistent with reach_col='clickCount'
|
495 |
ax.grid(True, linestyle='--', alpha=0.7)
|
496 |
plt.xticks(rotation=45)
|
497 |
-
|
498 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
499 |
return fig
|
500 |
except Exception as e:
|
@@ -535,7 +533,7 @@ def generate_impressions_over_time_plot(df, date_column='published_at', impressi
|
|
535 |
ax.set_ylabel('Total Impressions')
|
536 |
ax.grid(True, linestyle='--', alpha=0.7)
|
537 |
plt.xticks(rotation=45)
|
538 |
-
|
539 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
540 |
return fig
|
541 |
except Exception as e:
|
@@ -571,7 +569,7 @@ def generate_likes_over_time_plot(df, date_column='published_at', likes_col='lik
|
|
571 |
ax.set_ylabel('Total Likes')
|
572 |
ax.grid(True, linestyle='--', alpha=0.7)
|
573 |
plt.xticks(rotation=45)
|
574 |
-
|
575 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
576 |
return fig
|
577 |
except Exception as e:
|
@@ -585,7 +583,7 @@ def generate_clicks_over_time_plot(df, date_column='published_at', clicks_col='c
|
|
585 |
title = "Clicks Over Time"
|
586 |
logging.info(f"Generating {title}. Date: '{date_column}', Clicks Col: '{clicks_col}'. DF rows: {len(df) if df is not None else 'None'}")
|
587 |
# This function essentially calls generate_reach_over_time_plot with specific params
|
588 |
-
# The fig.subplots_adjust will be handled within that function.
|
589 |
return generate_reach_over_time_plot(df, date_column, clicks_col)
|
590 |
|
591 |
|
@@ -615,7 +613,7 @@ def generate_shares_over_time_plot(df, date_column='published_at', shares_col='s
|
|
615 |
ax.set_ylabel('Total Shares')
|
616 |
ax.grid(True, linestyle='--', alpha=0.7)
|
617 |
plt.xticks(rotation=45)
|
618 |
-
|
619 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
620 |
return fig
|
621 |
except Exception as e:
|
@@ -651,7 +649,7 @@ def generate_comments_over_time_plot(df, date_column='published_at', comments_co
|
|
651 |
ax.set_ylabel('Total Comments')
|
652 |
ax.grid(True, linestyle='--', alpha=0.7)
|
653 |
plt.xticks(rotation=45)
|
654 |
-
|
655 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
656 |
return fig
|
657 |
except Exception as e:
|
@@ -692,7 +690,7 @@ def generate_comments_sentiment_breakdown_plot(df, sentiment_column='comment_sen
|
|
692 |
ax.pie(sentiment_counts, labels=sentiment_counts.index, autopct='%1.1f%%', startangle=90, colors=pie_colors)
|
693 |
ax.set_title(title, y=1.03) # Matplotlib title
|
694 |
ax.axis('equal')
|
695 |
-
|
696 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
697 |
return fig
|
698 |
except Exception as e:
|
@@ -733,7 +731,7 @@ def generate_post_frequency_plot(df, date_column='published_at', resample_period
|
|
733 |
ax.set_ylabel('Number of Posts')
|
734 |
ax.grid(True, linestyle='--', alpha=0.7)
|
735 |
plt.xticks(rotation=45)
|
736 |
-
|
737 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
738 |
logging.info(f"Successfully generated {title} plot.")
|
739 |
return fig
|
@@ -772,7 +770,7 @@ def generate_content_format_breakdown_plot(df, format_col='media_type'):
|
|
772 |
for i, v in enumerate(format_counts):
|
773 |
ax.text(i, v + (0.01 * format_counts.max()), str(v), ha='center', va='bottom')
|
774 |
|
775 |
-
|
776 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
777 |
logging.info(f"Successfully generated {title} plot.")
|
778 |
return fig
|
@@ -832,7 +830,7 @@ def generate_content_topic_breakdown_plot(df, topics_col='eb_labels', top_n=15):
|
|
832 |
for i, (topic, count) in enumerate(top_topics.items()):
|
833 |
ax.text(count + (0.01 * top_topics.max()), i, str(count), va='center')
|
834 |
|
835 |
-
|
836 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
837 |
logging.info(f"Successfully generated {title} plot.")
|
838 |
return fig
|
|
|
16 |
fig, ax = plt.subplots(figsize=(8, 4))
|
17 |
ax.text(0.5, 0.5, f"{title}\n{message}", ha='center', va='center', fontsize=10, wrap=True)
|
18 |
ax.axis('off')
|
19 |
+
fig.tight_layout() # MODIFIED
|
20 |
# Add spacing for consistency, though it might be less critical for placeholders
|
21 |
fig.subplots_adjust(top=0.90)
|
22 |
return fig
|
|
|
26 |
fig_err, ax_err = plt.subplots()
|
27 |
ax_err.text(0.5, 0.5, "Fatal: Plot generation error", ha='center', va='center')
|
28 |
ax_err.axis('off')
|
29 |
+
fig_err.tight_layout() # MODIFIED
|
30 |
fig_err.subplots_adjust(top=0.90)
|
31 |
return fig_err
|
32 |
# No plt.close(fig) here as Gradio handles the figure object.
|
|
|
65 |
ax.set_ylabel('Number of Posts')
|
66 |
ax.grid(True, linestyle='--', alpha=0.7)
|
67 |
plt.xticks(rotation=45)
|
68 |
+
fig.tight_layout() # MODIFIED
|
69 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
70 |
logging.info("Successfully generated posts activity plot.")
|
71 |
return fig
|
|
|
74 |
if fig: plt.close(fig) # Close if fig was created before error
|
75 |
return create_placeholder_plot(title="Posts Activity Error", message=str(e))
|
76 |
finally:
|
77 |
+
pass
|
|
|
|
|
|
|
78 |
|
79 |
|
80 |
def generate_engagement_type_plot(df, likes_col='likeCount', comments_col='commentCount', shares_col='shareCount'):
|
|
|
123 |
yval = bar.get_height()
|
124 |
ax.text(bar.get_x() + bar.get_width()/2.0, yval + (0.01 * max(engagement_data.values(), default=10)), str(int(yval)), ha='center', va='bottom')
|
125 |
|
126 |
+
fig.tight_layout() # MODIFIED
|
127 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
128 |
logging.info("Successfully generated engagement type plot.")
|
129 |
return fig
|
|
|
168 |
ax.set_ylabel('Number of Mentions')
|
169 |
ax.grid(True, linestyle='--', alpha=0.7)
|
170 |
plt.xticks(rotation=45)
|
171 |
+
fig.tight_layout() # MODIFIED
|
172 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
173 |
logging.info("Successfully generated mentions activity plot.")
|
174 |
return fig
|
|
|
205 |
ax.pie(sentiment_counts, labels=sentiment_counts.index, autopct='%1.1f%%', startangle=90, colors=pie_colors)
|
206 |
ax.set_title('Mention Sentiment Distribution', y=1.03) # Matplotlib title
|
207 |
ax.axis('equal')
|
208 |
+
fig.tight_layout() # MODIFIED
|
209 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
210 |
logging.info("Successfully generated mention sentiment plot.")
|
211 |
return fig
|
|
|
259 |
ax.legend()
|
260 |
ax.grid(True, linestyle='--', alpha=0.7)
|
261 |
plt.xticks(rotation=45)
|
262 |
+
fig.tight_layout() # MODIFIED
|
263 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
264 |
return fig
|
265 |
except Exception as e:
|
|
|
325 |
ax.legend()
|
326 |
ax.grid(True, linestyle='--', alpha=0.7)
|
327 |
plt.xticks(rotation=45)
|
328 |
+
fig.tight_layout() # MODIFIED
|
329 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
330 |
return fig
|
331 |
except Exception as e:
|
|
|
398 |
ax.text(bar_item.get_x() + bar_item.get_width()/2.0, yval + (0.01 * ax.get_ylim()[1]),
|
399 |
str(int(yval)), ha='center', va='bottom', fontsize=8)
|
400 |
|
401 |
+
fig.tight_layout() # MODIFIED
|
402 |
fig.subplots_adjust(top=0.85) # Adjust top for more space, especially with rotated labels
|
403 |
return fig
|
404 |
except Exception as e:
|
|
|
451 |
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=formatter_xmax))
|
452 |
ax.grid(True, linestyle='--', alpha=0.7)
|
453 |
plt.xticks(rotation=45)
|
454 |
+
fig.tight_layout() # MODIFIED
|
455 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
456 |
return fig
|
457 |
except Exception as e:
|
|
|
492 |
ax.set_ylabel('Total Clicks') # Label consistent with reach_col='clickCount'
|
493 |
ax.grid(True, linestyle='--', alpha=0.7)
|
494 |
plt.xticks(rotation=45)
|
495 |
+
fig.tight_layout() # MODIFIED
|
496 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
497 |
return fig
|
498 |
except Exception as e:
|
|
|
533 |
ax.set_ylabel('Total Impressions')
|
534 |
ax.grid(True, linestyle='--', alpha=0.7)
|
535 |
plt.xticks(rotation=45)
|
536 |
+
fig.tight_layout() # MODIFIED
|
537 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
538 |
return fig
|
539 |
except Exception as e:
|
|
|
569 |
ax.set_ylabel('Total Likes')
|
570 |
ax.grid(True, linestyle='--', alpha=0.7)
|
571 |
plt.xticks(rotation=45)
|
572 |
+
fig.tight_layout() # MODIFIED
|
573 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
574 |
return fig
|
575 |
except Exception as e:
|
|
|
583 |
title = "Clicks Over Time"
|
584 |
logging.info(f"Generating {title}. Date: '{date_column}', Clicks Col: '{clicks_col}'. DF rows: {len(df) if df is not None else 'None'}")
|
585 |
# This function essentially calls generate_reach_over_time_plot with specific params
|
586 |
+
# The fig.tight_layout() and fig.subplots_adjust will be handled within that function.
|
587 |
return generate_reach_over_time_plot(df, date_column, clicks_col)
|
588 |
|
589 |
|
|
|
613 |
ax.set_ylabel('Total Shares')
|
614 |
ax.grid(True, linestyle='--', alpha=0.7)
|
615 |
plt.xticks(rotation=45)
|
616 |
+
fig.tight_layout() # MODIFIED
|
617 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
618 |
return fig
|
619 |
except Exception as e:
|
|
|
649 |
ax.set_ylabel('Total Comments')
|
650 |
ax.grid(True, linestyle='--', alpha=0.7)
|
651 |
plt.xticks(rotation=45)
|
652 |
+
fig.tight_layout() # MODIFIED
|
653 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
654 |
return fig
|
655 |
except Exception as e:
|
|
|
690 |
ax.pie(sentiment_counts, labels=sentiment_counts.index, autopct='%1.1f%%', startangle=90, colors=pie_colors)
|
691 |
ax.set_title(title, y=1.03) # Matplotlib title
|
692 |
ax.axis('equal')
|
693 |
+
fig.tight_layout() # MODIFIED
|
694 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
695 |
return fig
|
696 |
except Exception as e:
|
|
|
731 |
ax.set_ylabel('Number of Posts')
|
732 |
ax.grid(True, linestyle='--', alpha=0.7)
|
733 |
plt.xticks(rotation=45)
|
734 |
+
fig.tight_layout() # MODIFIED
|
735 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
736 |
logging.info(f"Successfully generated {title} plot.")
|
737 |
return fig
|
|
|
770 |
for i, v in enumerate(format_counts):
|
771 |
ax.text(i, v + (0.01 * format_counts.max()), str(v), ha='center', va='bottom')
|
772 |
|
773 |
+
fig.tight_layout() # MODIFIED
|
774 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
775 |
logging.info(f"Successfully generated {title} plot.")
|
776 |
return fig
|
|
|
830 |
for i, (topic, count) in enumerate(top_topics.items()):
|
831 |
ax.text(count + (0.01 * top_topics.max()), i, str(count), va='center')
|
832 |
|
833 |
+
fig.tight_layout() # MODIFIED
|
834 |
fig.subplots_adjust(top=0.88) # Add space for Gradio label
|
835 |
logging.info(f"Successfully generated {title} plot.")
|
836 |
return fig
|