Install
$ agentstack add skill-curiouslearner-devkit-chart-generator ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Chart Generator Skill
Generate charts and visualizations from data using various charting libraries and formats.
Instructions
You are a data visualization expert. When invoked:
- Analyze Data:
- Understand data structure and types
- Identify appropriate chart types
- Detect data patterns and trends
- Calculate aggregations and statistics
- Determine visualization goals
- Generate Charts:
- Create bar, line, pie, scatter plots
- Generate heatmaps and tree maps
- Create histograms and box plots
- Build time series visualizations
- Design multi-dimensional charts
- Style and Customize:
- Apply color schemes and themes
- Add labels, legends, and annotations
- Format axes and gridlines
- Customize tooltips and interactions
- Ensure accessibility and readability
- Export and Embed:
- Save as PNG, SVG, PDF
- Generate interactive HTML charts
- Embed in markdown reports
- Create chart APIs
- Support responsive design
Usage Examples
@chart-generator data.csv --type bar
@chart-generator --line --time-series
@chart-generator --pie --group-by category
@chart-generator --scatter x:age y:income
@chart-generator --heatmap --correlation
@chart-generator --interactive --html
Chart Types and Use Cases
When to Use Each Chart Type
| Chart Type | Best For | Example Use Case | |------------|----------|------------------| | Bar Chart | Comparing categories | Sales by product | | Line Chart | Trends over time | Revenue over months | | Pie Chart | Part-to-whole relationships | Market share | | Scatter Plot | Relationships between variables | Height vs Weight | | Histogram | Distribution of values | Age distribution | | Box Plot | Statistical distribution | Salary ranges by department | | Heatmap | Matrix data, correlations | Feature correlations | | Area Chart | Cumulative trends | Stacked revenue streams | | Bubble Chart | 3-dimensional data | Sales vs Profit vs Market Share | | Treemap | Hierarchical data | Disk space usage |
Python - Matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
def create_bar_chart(data, x_col, y_col, title='Bar Chart', output='chart.png'):
"""
Create a bar chart
"""
plt.figure(figsize=(10, 6))
if isinstance(data, pd.DataFrame):
x = data[x_col]
y = data[y_col]
else:
x = data['labels']
y = data['values']
bars = plt.bar(x, y, color='steelblue', alpha=0.8)
# Add value labels on bars
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height,
f'{height:.1f}',
ha='center', va='bottom')
plt.title(title, fontsize=16, fontweight='bold')
plt.xlabel(x_col if isinstance(data, pd.DataFrame) else 'Category', fontsize=12)
plt.ylabel(y_col if isinstance(data, pd.DataFrame) else 'Value', fontsize=12)
plt.xticks(rotation=45, ha='right')
plt.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
def create_line_chart(data, x_col, y_col, title='Line Chart', output='chart.png'):
"""
Create a line chart
"""
plt.figure(figsize=(12, 6))
if isinstance(data, pd.DataFrame):
x = data[x_col]
y = data[y_col]
else:
x = data['x']
y = data['y']
plt.plot(x, y, marker='o', linewidth=2, markersize=6, color='steelblue')
# Add grid
plt.grid(True, alpha=0.3)
plt.title(title, fontsize=16, fontweight='bold')
plt.xlabel(x_col if isinstance(data, pd.DataFrame) else 'X', fontsize=12)
plt.ylabel(y_col if isinstance(data, pd.DataFrame) else 'Y', fontsize=12)
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
def create_pie_chart(data, labels_col, values_col, title='Pie Chart', output='chart.png'):
"""
Create a pie chart
"""
plt.figure(figsize=(10, 8))
if isinstance(data, pd.DataFrame):
labels = data[labels_col]
values = data[values_col]
else:
labels = data['labels']
values = data['values']
# Create color palette
colors = plt.cm.Set3(np.linspace(0, 1, len(labels)))
# Create pie chart
wedges, texts, autotexts = plt.pie(
values,
labels=labels,
autopct='%1.1f%%',
startangle=90,
colors=colors,
explode=[0.05] * len(labels) # Slightly separate slices
)
# Style percentage text
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontweight('bold')
autotext.set_fontsize(10)
plt.title(title, fontsize=16, fontweight='bold')
plt.axis('equal')
plt.tight_layout()
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
def create_scatter_plot(data, x_col, y_col, color_col=None, size_col=None,
title='Scatter Plot', output='chart.png'):
"""
Create a scatter plot
"""
plt.figure(figsize=(10, 8))
if isinstance(data, pd.DataFrame):
x = data[x_col]
y = data[y_col]
c = data[color_col] if color_col else None
s = data[size_col] if size_col else 50
else:
x = data['x']
y = data['y']
c = None
s = 50
scatter = plt.scatter(x, y, c=c, s=s, alpha=0.6, cmap='viridis')
if color_col:
plt.colorbar(scatter, label=color_col)
# Add trend line
z = np.polyfit(x, y, 1)
p = np.poly1d(z)
plt.plot(x, p(x), "r--", alpha=0.8, label='Trend')
plt.title(title, fontsize=16, fontweight='bold')
plt.xlabel(x_col if isinstance(data, pd.DataFrame) else 'X', fontsize=12)
plt.ylabel(y_col if isinstance(data, pd.DataFrame) else 'Y', fontsize=12)
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
def create_histogram(data, column, bins=30, title='Histogram', output='chart.png'):
"""
Create a histogram
"""
plt.figure(figsize=(10, 6))
if isinstance(data, pd.DataFrame):
values = data[column]
else:
values = data
n, bins, patches = plt.hist(values, bins=bins, color='steelblue',
alpha=0.7, edgecolor='black')
# Add mean line
mean_val = np.mean(values)
plt.axvline(mean_val, color='red', linestyle='dashed', linewidth=2,
label=f'Mean: {mean_val:.2f}')
# Add median line
median_val = np.median(values)
plt.axvline(median_val, color='green', linestyle='dashed', linewidth=2,
label=f'Median: {median_val:.2f}')
plt.title(title, fontsize=16, fontweight='bold')
plt.xlabel(column if isinstance(data, pd.DataFrame) else 'Value', fontsize=12)
plt.ylabel('Frequency', fontsize=12)
plt.legend()
plt.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
def create_box_plot(data, columns, title='Box Plot', output='chart.png'):
"""
Create a box plot
"""
plt.figure(figsize=(10, 6))
if isinstance(data, pd.DataFrame):
data_to_plot = [data[col].dropna() for col in columns]
labels = columns
else:
data_to_plot = data
labels = [f'Group {i+1}' for i in range(len(data))]
bp = plt.boxplot(data_to_plot, labels=labels, patch_artist=True)
# Color boxes
for patch in bp['boxes']:
patch.set_facecolor('lightblue')
patch.set_alpha(0.7)
plt.title(title, fontsize=16, fontweight='bold')
plt.ylabel('Value', fontsize=12)
plt.grid(axis='y', alpha=0.3)
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
def create_heatmap(data, title='Heatmap', output='chart.png'):
"""
Create a heatmap (correlation matrix)
"""
plt.figure(figsize=(10, 8))
if isinstance(data, pd.DataFrame):
# Calculate correlation matrix
corr_matrix = data.corr()
else:
corr_matrix = data
# Create heatmap
im = plt.imshow(corr_matrix, cmap='coolwarm', aspect='auto',
vmin=-1, vmax=1)
# Add colorbar
cbar = plt.colorbar(im)
cbar.set_label('Correlation', rotation=270, labelpad=20)
# Set ticks and labels
plt.xticks(range(len(corr_matrix.columns)), corr_matrix.columns,
rotation=45, ha='right')
plt.yticks(range(len(corr_matrix.columns)), corr_matrix.columns)
# Add correlation values
for i in range(len(corr_matrix)):
for j in range(len(corr_matrix.columns)):
text = plt.text(j, i, f'{corr_matrix.iloc[i, j]:.2f}',
ha='center', va='center', color='black', fontsize=9)
plt.title(title, fontsize=16, fontweight='bold', pad=20)
plt.tight_layout()
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
Python - Seaborn
import seaborn as sns
def create_seaborn_chart(data, chart_type, x, y=None, hue=None,
title='Chart', output='chart.png'):
"""
Create charts using Seaborn
"""
plt.figure(figsize=(12, 6))
# Set style
sns.set_style("whitegrid")
sns.set_palette("husl")
if chart_type == 'bar':
sns.barplot(data=data, x=x, y=y, hue=hue)
elif chart_type == 'line':
sns.lineplot(data=data, x=x, y=y, hue=hue, marker='o')
elif chart_type == 'scatter':
sns.scatterplot(data=data, x=x, y=y, hue=hue, size=hue, alpha=0.6)
elif chart_type == 'box':
sns.boxplot(data=data, x=x, y=y, hue=hue)
elif chart_type == 'violin':
sns.violinplot(data=data, x=x, y=y, hue=hue)
elif chart_type == 'dist':
sns.histplot(data=data, x=x, hue=hue, kde=True)
elif chart_type == 'heatmap':
sns.heatmap(data.corr(), annot=True, fmt='.2f', cmap='coolwarm',
center=0, square=True, linewidths=1)
elif chart_type == 'pairplot':
# Special case - creates its own figure
g = sns.pairplot(data, hue=hue)
g.savefig(output, dpi=300, bbox_inches='tight')
return output
plt.title(title, fontsize=16, fontweight='bold')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
# Advanced Seaborn visualizations
def create_facet_grid(data, x, y, col=None, row=None, hue=None,
title='Facet Grid', output='chart.png'):
"""
Create faceted charts
"""
g = sns.FacetGrid(data, col=col, row=row, hue=hue, height=4)
g.map(sns.scatterplot, x, y, alpha=0.6)
g.add_legend()
g.fig.suptitle(title, y=1.02, fontsize=16, fontweight='bold')
plt.savefig(output, dpi=300, bbox_inches='tight')
plt.close()
return output
JavaScript - Chart.js
const { ChartJSNodeCanvas } = require('chartjs-node-canvas');
async function createBarChart(data, options = {}) {
const width = options.width || 800;
const height = options.height || 600;
const chartJSNodeCanvas = new ChartJSNodeCanvas({ width, height });
const configuration = {
type: 'bar',
data: {
labels: data.labels,
datasets: [{
label: options.label || 'Dataset',
data: data.values,
backgroundColor: 'rgba(54, 162, 235, 0.6)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 2
}]
},
options: {
responsive: true,
plugins: {
title: {
display: true,
text: options.title || 'Bar Chart',
font: { size: 18 }
},
legend: {
display: true,
position: 'top'
}
},
scales: {
y: {
beginAtZero: true
}
}
}
};
const imageBuffer = await chartJSNodeCanvas.renderToBuffer(configuration);
return imageBuffer;
}
async function createLineChart(data, options = {}) {
const width = options.width || 800;
const height = options.height || 600;
const chartJSNodeCanvas = new ChartJSNodeCanvas({ width, height });
const configuration = {
type: 'line',
data: {
labels: data.labels,
datasets: [{
label: options.label || 'Dataset',
data: data.values,
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderWidth: 2,
tension: 0.4
}]
},
options: {
responsive: true,
plugins: {
title: {
display: true,
text: options.title || 'Line Chart',
font: { size: 18 }
}
},
scales: {
y: {
beginAtZero: true
}
}
}
};
const imageBuffer = await chartJSNodeCanvas.renderToBuffer(configuration);
return imageBuffer;
}
async function createPieChart(data, options = {}) {
const width = options.width || 800;
const height = options.height || 600;
const chartJSNodeCanvas = new ChartJSNodeCanvas({ width, height });
const configuration = {
type: 'pie',
data: {
labels: data.labels,
datasets: [{
data: data.values,
backgroundColor: [
'rgba(255, 99, 132, 0.6)',
'rgba(54, 162, 235, 0.6)',
'rgba(255, 206, 86, 0.6)',
'rgba(75, 192, 192, 0.6)',
'rgba(153, 102, 255, 0.6)',
'rgba(255, 159, 64, 0.6)'
],
borderWidth: 2
}]
},
options: {
responsive: true,
plugins: {
title: {
display: true,
text: options.title || 'Pie Chart',
font: { size: 18 }
},
legend: {
position: 'right'
}
}
}
};
const imageBuffer = await chartJSNodeCanvas.renderToBuffer(configuration);
return imageBuffer;
}
Interactive Charts - Plotly
import plotly.express as px
import plotly.graph_objects as go
def create_interactive_bar(data, x, y, title='Bar Chart', output='chart.html'):
"""
Create interactive bar chart with Plotly
"""
fig = px.bar(data, x=x, y=y, title=title,
color=y, color_continuous_scale='Viridis')
fig.update_layout(
font=dict(size=14),
showlegend=True,
hovermode='x unified'
)
fig.write_html(output)
return output
def create_interactive_line(data, x, y, title='Line Chart', output='chart.html'):
"""
Create interactive line chart
"""
fig = px.line(data, x=x, y=y, title=title, markers=True)
fig.update_traces(line=dict(width=3))
fig.update_layout(
hovermode='x unified',
font=dict(size=14)
)
fig.write_html(output)
return output
def create_interactive_scatter(data, x, y, color=None, size=None,
title='Scatter Plot', output='chart.html'):
"""
Create interactive scatter plot
"""
fig = px.scatter(data, x=x, y=y, color=color, size=size,
title=title, hover_data=data.columns)
fig.update_traces(marker=dict(line=dict(width=0.5, color='white')))
fig.write_html(output)
return output
def create_3d_scatter(data, x, y, z, color=None, title='3D Scatter',
output='chart.html'):
"""
Create 3D scatter plot
"""
fig = px.scatter_3d(data, x=x, y=y, z=z, color=color, title=title)
fig.update_layout(scene=dict(
xaxis_title=x,
yaxis_title=y,
zaxis_title=z
))
fig.write_html(output)
return output
def create_time_series(data, date_col, value_col, title='Time Series',
output='chart.html'):
"""
Create time series chart
"""
fig = go.Fig
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [CuriousLearner](https://github.com/CuriousLearner)
- **Source:** [CuriousLearner/devkit](https://github.com/CuriousLearner/devkit)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.