seb1n/data-visualization
Create clear, effective charts and dashboards from structured data using matplotlib, seaborn, and plotly.
npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill data-visualization
This skill enables an AI agent to transform structured data into meaningful visual representations. The agent selects appropriate chart types based on the data and the question being asked, builds publication-quality static charts with matplotlib and seaborn, and creates interactive visualizations with plotly. It follows established data visualization principles to ensure clarity, accuracy, and visual appeal.
| Goal | Chart Type | Library |
|------|-----------|---------|
| Compare categories | Bar chart (vertical or horizontal) | matplotlib, seaborn |
| Show trend over time | Line chart | matplotlib, plotly |
| Explore relationship between 2 variables | Scatter plot | seaborn, plotly |
| Show distribution of a variable | Histogram or KDE | seaborn |
| Compare distributions across groups | Box plot or violin plot | seaborn |
| Display correlation matrix | Heatmap | seaborn |
| Show composition / proportions | Stacked bar or pie chart | matplotlib |
| Enable user exploration | Interactive chart | plotly |
Provide the agent with a dataset and a description of what you want to visualize. Optionally specify chart type, color preferences, output format, and figure dimensions. The agent will select the best approach if no chart type is specified.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv("quarterly_sales.csv", parse_dates=["date"])
sns.set_theme(style="whitegrid", palette="viridis")
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle("Q4 2024 Sales Dashboard", fontsize=16, fontweight="bold")
# 1. Monthly revenue trend
monthly = df.resample("M", on="date")["revenue"].sum()
axes[0, 0].plot(monthly.index, monthly.values, marker="o", linewidth=2)
axes[0, 0].set_title("Monthly Revenue Trend")
axes[0, 0].set_ylabel("Revenue ($)")
axes[0, 0].tick_params(axis="x", rotation=45)
# 2. Revenue by region (horizontal bar)
region = df.groupby("region")["revenue"].sum().sort_values()
axes[0, 1].barh(region.index, region.values, color=sns.color_palette("viridis", len(region)))
axes[0, 1].set_title("Revenue by Region")
axes[0, 1].set_xlabel("Total Revenue ($)")
# 3. Units sold distribution (histogram)
axes[1, 0].hist(df["units_sold"], bins=30, edgecolor="white", alpha=0.8)
axes[1, 0].axvline(df["units_sold"].median(), color="red", linestyle="--", label="Median")
axes[1, 0].set_title("Units Sold Distribution")
axes[1, 0].legend()
# 4. Revenue vs. discount scatter with regression
sns.regplot(data=df, x="discount", y="revenue", ax=axes[1, 1],
scatter_kws={"alpha": 0.4, "s": 15}, line_kws={"color": "red"})
axes[1, 1].set_title("Revenue vs. Discount")
plt.tight_layout()
plt.savefig("sales_dashboard.png", dpi=150, bbox_inches="tight")
plt.show()
import pandas as pd
import plotly.express as px
df = pd.read_csv("global_sales.csv")
# Interactive scatter with size, color, and hover data
fig = px.scatter(
df,
x="marketing_spend",
y="revenue",
size="units_sold",
color="region",
hover_data=["product_name", "quarter"],
title="Marketing Spend vs Revenue by Region",
labels={
"marketing_spend": "Marketing Spend ($)",
"revenue": "Revenue ($)",
"units_sold": "Units Sold"
},
template="plotly_white"
)
fig.update_traces(marker=dict(opacity=0.7, line=dict(width=1, color="DarkSlateGrey")))
# Add a trend line annotation
fig.add_annotation(
x=45000, y=320000,
text="Strong ROI cluster:<br>low spend, high revenue",
showarrow=True, arrowhead=2,
font=dict(size=12, color="darkblue")
)
fig.write_html("interactive_scatter.html")
fig.show()
# Users can hover over points to see product_name and quarter,
# zoom into clusters, and toggle regions on/off via the legend.
alpha=0.3), jitter, or hexbin/2D density plots when thousands of points overlap.Take seb1n/data-visualization from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.