Visualization with ySights
This tutorial demonstrates ySights’ built-in visualization capabilities for creating publication-ready plots.
What You’ll Learn
Global trends visualization
Topic evolution plots
Profile similarity visualizations
Sentiment and exposure diagnostics
Multiplex interaction plots
Recommendation system plots
Summary and moderation diagnostic charts
[ ]:
from pathlib import Path
from ysights import YDataHandler
from ysights import viz, algorithms
from ysights.algorithms import sentiment_diffusion_metrics
from ysights.algorithms.topics import topic_spread, adoption_rate, peak_engagement_time
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
[ ]:
# Initialize data handler and network
from pathlib import Path
def resolve_example_db():
candidates = [
Path("ysocial_db.db"),
Path("../notebooks/ysocial_db.db"),
Path("../../notebooks/ysocial_db.db"),
Path("docs/notebooks/ysocial_db.db"),
]
for candidate in candidates:
if candidate.exists():
return str(candidate.resolve())
return "ysocial_db.db"
db_path = resolve_example_db()
ydh = YDataHandler(db_path)
network = ydh.social_network()
1. Global Trends Visualization
Daily Content Trends
Visualize how content creation changes over time.
[ ]:
fig = viz.daily_contents_trends(ydh)
plt.tight_layout()
plt.show()
print("This plot shows the number of posts created each day throughout the simulation.")
Daily Reactions Trends
Analyze how user engagement (likes, reactions) evolves.
[ ]:
fig = viz.daily_reactions_trends(ydh)
plt.tight_layout()
plt.show()
print("This shows user engagement patterns over time.")
Content per User Distribution
Show how many posts each user creates.
[ ]:
fig = viz.contents_per_user_distributions(ydh)
plt.tight_layout()
plt.show()
print("Distribution of content creation across users (log-log scale).")
Trending Emotions
Analyze the emotional content of posts.
[ ]:
fig = viz.trending_emotions(ydh)
plt.tight_layout()
plt.show()
print("Distribution of emotions in posts.")
Trending Topics
Identify the most discussed topics.
[ ]:
fig = viz.tending_topics(ydh, limit=10)
plt.tight_layout()
plt.show()
print("Top 10 most discussed topics.")
Comments Distribution
Analyze how many comments posts receive.
[ ]:
fig = viz.comments_per_post_distribution(ydh)
plt.tight_layout()
plt.show()
print("Distribution of comments per post.")
2. Topic Visualization
Topic Density Temporal Evolution
Visualize how topic interest evolves over time (requires Plotly).
[ ]:
try:
fig = viz.topic_density_temporal_evolution(ydh, min_days=15)
fig.show()
print("Interactive plot showing topic evolution over time.")
print("Hover over the heatmap to see detailed information.")
except Exception as e:
print(f"Could not create plot: {e}")
print("Make sure plotly is installed: pip install plotly")
3. Summary and Diagnostics
Summary Snapshot
Start with a compact dataset overview before plotting the more detailed views.
[ ]:
summary_frame = ydh.summary_frame()
summary_report = ydh.summary_report()
print("Summary frame:")
print(summary_frame.to_string(index=False))
print("\nCache diagnostics:")
print(ydh.analysis_cache_info())
print("\nRecommended indexes:")
print(ydh.recommended_indexes())
Moderation Hotspots
Visualize the most frequently reported users and posts.
[ ]:
hotspots = ydh.moderation_hotspots(top_n=10)
if hotspots.empty:
print("No moderation hotspots were found in this database.")
else:
labels = [f"{row.entity_type}:{row.entity_id}" for row in hotspots.itertuples(index=False)]
plt.figure(figsize=(10, 6))
plt.barh(labels, hotspots["report_count"], color="firebrick", alpha=0.8)
plt.gca().invert_yaxis()
plt.xlabel("Report count")
plt.ylabel("Entity")
plt.title("Top Moderation Hotspots", fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3, axis='x')
plt.tight_layout()
plt.show()
Topic Lifecycle Scatter
Use lifecycle metrics to compare topic spread, adoption, and peak engagement.
[ ]:
lifecycles = topic_spread(ydh)
adoption_rates = adoption_rate(ydh)
peak_periods = peak_engagement_time(ydh)
topic_ids = list(lifecycles.keys())
if not topic_ids:
print("No topic lifecycle data is available in this database.")
else:
spread_values = [lifecycles[topic_id]["post_count"] for topic_id in topic_ids]
adoption_values = [adoption_rates[topic_id] for topic_id in topic_ids]
peak_values = [peak_periods[topic_id] for topic_id in topic_ids]
plt.figure(figsize=(10, 6))
scatter = plt.scatter(
adoption_values,
spread_values,
c=peak_values,
cmap="viridis",
s=90,
alpha=0.85,
edgecolor="black",
linewidth=0.4,
)
plt.colorbar(scatter, label="Peak period")
plt.xlabel("Adoption rate")
plt.ylabel("Topic spread (post count)")
plt.title("Topic Lifecycle Snapshot", fontsize=14, fontweight='bold')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
4. Profile Similarity Visualization
Profile Similarity Distribution
Visualize the distribution of similarity scores.
[ ]:
similarity = algorithms.profile_topics_similarity(ydh, network)
fig = viz.profile_similarity_distribution([similarity], ['All Users'])
plt.tight_layout()
plt.show()
print("Distribution of profile similarity scores across all users.")
Similarity vs. Network Degree
Analyze the relationship between network position and profile similarity.
[ ]:
fig = viz.profile_similarity_vs_degree([similarity], [network], ["All Users"])
plt.tight_layout()
plt.show()
print("Relationship between user connectivity and profile similarity.")
Binned Similarity per Degree
Show average similarity for users grouped by their network degree.
[ ]:
fig = viz.binned_similarity_per_degree([similarity], [network], ["All Users"], bins=10)
plt.tight_layout()
plt.show()
print("Average similarity scores grouped by network degree bins.")
5. Recommendation System Visualization
Recommendations per Post
Analyze how many times posts are recommended.
[ ]:
fig = viz.recommendations_per_post_distribution(ydh)
plt.tight_layout()
plt.show()
print("Distribution of recommendations per post.")
Recommendations vs. Reactions
Analyze the relationship between recommendations and user reactions.
[ ]:
fig = viz.recommendations_vs_reactions(ydh)
plt.tight_layout()
plt.show()
print("Relationship between number of recommendations and reactions received.")
Recommendations vs. Comments
Analyze how recommendations affect comment engagement.
[ ]:
fig = viz.recommendations_vs_comments(ydh)
plt.tight_layout()
plt.show()
print("Relationship between recommendations and comments.")
6. Semantic, Sentiment, and Multiplex Diagnostics
These plots summarize the newly added semantic and multiplex analytics in compact, notebook-friendly visuals.
Semantic profile snapshot
Plot a few semantic metrics for a representative post.
[ ]:
agent_id = next(iter(ydh.agent_mapping()))
sample_posts = ydh.posts_by_agent(agent_id).get_posts()
if sample_posts:
sample_post = sample_posts[0]
post_profile = ydh.post_semantic_profile(sample_post.id)
semantic_metrics = {
"lexical_diversity": post_profile["lexical_diversity"],
"readability_proxy": post_profile["readability_proxy"],
"punctuation_intensity": post_profile["punctuation_intensity"],
}
fig, ax = plt.subplots(figsize=(8, 4))
ax.bar(semantic_metrics.keys(), semantic_metrics.values(), color="#C85C5C")
ax.set_title(f"Semantic profile for post {sample_post.id}")
ax.set_ylabel("Score")
ax.grid(axis="y", alpha=0.3)
plt.tight_layout()
plt.show()
else:
print("No sample posts were found in this dataset.")
Sentiment diffusion timeline
Plot how sentiment labels and recommended exposures evolve across rounds.
[ ]:
diffusion = sentiment_diffusion_metrics(ydh)
timeline = diffusion["timeline"]
if timeline.empty:
print("No sentiment timeline data is available in this dataset.")
else:
fig, ax1 = plt.subplots(figsize=(10, 4))
ax1.plot(timeline["round"], timeline["positive_posts"], label="Positive posts", color="#2E8B57")
ax1.plot(timeline["round"], timeline["negative_posts"], label="Negative posts", color="#B22222")
ax1.plot(timeline["round"], timeline["neutral_posts"], label="Neutral posts", color="#555555")
ax1.set_xlabel("Round")
ax1.set_ylabel("Post count")
ax1.set_title("Sentiment diffusion by round")
ax1.grid(alpha=0.3)
ax1.legend(loc="upper left")
ax2 = ax1.twinx()
ax2.plot(
timeline["round"],
timeline["recommended_exposures"],
label="Recommended exposures",
color="#1F77B4",
linestyle="--",
)
ax2.set_ylabel("Recommended exposures")
ax2.legend(loc="upper right")
plt.tight_layout()
plt.show()
Multiplex layer comparison
Compare the edge counts for the available interaction layers and inspect the combined graph diagnostics.
[ ]:
multiplex = ydh.multiplex_metrics()
layer_names = list(multiplex["layer_metrics"].keys())
layer_edge_counts = [multiplex["layer_metrics"][name]["edge_count"] for name in layer_names]
fig, ax = plt.subplots(figsize=(8, 4))
ax.bar(layer_names, layer_edge_counts, color="#4F81BD")
ax.set_title("Interaction layer edge counts")
ax.set_ylabel("Edges")
ax.grid(axis="y", alpha=0.3)
plt.tight_layout()
plt.show()
print("Combined polarization summary:")
print(multiplex["combined_polarization"])
7. Saving Visualizations
Save plots for publications or presentations.