chart-generator
About
The chart-generator skill creates data visualizations like bar, line, and scatter plots from provided datasets. It analyzes data structure to determine the best chart type and applies custom styling, labels, and themes. Developers should use this skill to quickly generate and embed charts directly within their Claude Code workflows.
Documentation
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.Figure()
fig.add_trace(go.Scatter(
x=data[date_col],
y=data[value_col],
mode='lines+markers',
name=value_col,
line=dict(width=2),
marker=dict(size=6)
))
# Add range slider
fig.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=7, label="1w", step="day", stepmode="backward"),
dict(count=1, label="1m", step="month", stepmode="backward"),
dict(count=3, label="3m", step="month", stepmode="backward"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(step="all")
])
)
)
fig.update_layout(
title=title,
xaxis_title=date_col,
yaxis_title=value_col,
font=dict(size=14)
)
fig.write_html(output)
return output
def create_dashboard(data, output='dashboard.html'):
"""
Create multi-chart dashboard
"""
from plotly.subplots import make_subplots
fig = make_subplots(
rows=2, cols=2,
subplot_titles=('Bar Chart', 'Line Chart', 'Pie Chart', 'Scatter Plot'),
specs=[[{'type': 'bar'}, {'type': 'scatter'}],
[{'type': 'pie'}, {'type': 'scatter'}]]
)
# Add charts
# Bar chart
fig.add_trace(
go.Bar(x=data['category'], y=data['value1'], name='Bar'),
row=1, col=1
)
# Line chart
fig.add_trace(
go.Scatter(x=data['date'], y=data['value2'], mode='lines', name='Line'),
row=1, col=2
)
# Pie chart
fig.add_trace(
go.Pie(labels=data['category'], values=data['value1'], name='Pie'),
row=2, col=1
)
# Scatter plot
fig.add_trace(
go.Scatter(x=data['value1'], y=data['value2'], mode='markers', name='Scatter'),
row=2, col=2
)
fig.update_layout(height=800, showlegend=True, title_text="Dashboard")
fig.write_html(output)
return output
Chart Styling and Themes
# Matplotlib themes
def apply_matplotlib_theme(theme='default'):
"""
Apply theme to matplotlib charts
"""
themes = {
'default': 'seaborn-v0_8-darkgrid',
'minimal': 'seaborn-v0_8-whitegrid',
'dark': 'dark_background',
'classic': 'classic',
'ggplot': 'ggplot'
}
plt.style.use(themes.get(theme, 'default'))
# Custom color palettes
COLOR_PALETTES = {
'corporate': ['#003f5c', '#58508d', '#bc5090', '#ff6361', '#ffa600'],
'pastel': ['#a8e6cf', '#dcedc1', '#ffd3b6', '#ffaaa5', '#ff8b94'],
'vibrant': ['#e74c3c', '#3498db', '#2ecc71', '#f39c12', '#9b59b6'],
'monochrome': ['#2c3e50', '#34495e', '#7f8c8d', '#95a5a6', '#bdc3c7']
}
def apply_color_palette(palette_name='corporate'):
"""Apply custom color palette"""
colors = COLOR_PALETTES.get(palette_name, COLOR_PALETTES['corporate'])
plt.rcParams['axes.prop_cycle'] = plt.cycler(color=colors)
Export Formats
def export_chart_multiple_formats(fig, base_name='chart'):
"""
Export chart in multiple formats
"""
formats = {
'png': {'dpi': 300, 'transparent': False},
'svg': {'format': 'svg'},
'pdf': {'format': 'pdf'},
'jpg': {'dpi': 300, 'format': 'jpg'}
}
files = []
for fmt, kwargs in formats.items():
output_file = f"{base_name}.{fmt}"
fig.savefig(output_file, bbox_inches='tight', **kwargs)
files.append(output_file)
return files
Chart Generation Pipeline
def generate_charts_from_data(data, chart_configs, output_dir='charts'):
"""
Generate multiple charts from data based on configurations
chart_configs = [
{
'type': 'bar',
'x': 'category',
'y': 'value',
'title': 'Sales by Category',
'output': 'sales_bar.png'
},
...
]
"""
import os
os.makedirs(output_dir, exist_ok=True)
generated_charts = []
for config in chart_configs:
chart_type = config['type']
output = os.path.join(output_dir, config['output'])
if chart_type == 'bar':
create_bar_chart(data, config['x'], config['y'],
config.get('title', 'Chart'), output)
elif chart_type == 'line':
create_line_chart(data, config['x'], config['y'],
config.get('title', 'Chart'), output)
elif chart_type == 'pie':
create_pie_chart(data, config['x'], config['y'],
config.get('title', 'Chart'), output)
elif chart_type == 'scatter':
create_scatter_plot(data, config['x'], config['y'],
config.get('color'), config.get('size'),
config.get('title', 'Chart'), output)
elif chart_type == 'heatmap':
create_heatmap(data, config.get('title', 'Chart'), output)
generated_charts.append({
'type': chart_type,
'title': config.get('title'),
'file': output
})
return generated_charts
Best Practices
- Choose appropriate chart types for your data
- Use clear, descriptive titles and labels
- Apply consistent color schemes across charts
- Ensure readability (font sizes, contrast)
- Add context (annotations, reference lines)
- Export in high resolution (300 DPI minimum)
- Consider accessibility (color-blind friendly palettes)
- Test on different screen sizes (responsive design)
- Optimize file sizes for web use
- Document chart generation code for reproducibility
Common Chart Patterns
Comparison Charts
- Bar charts for categorical comparisons
- Grouped bar charts for multi-series comparison
- Stacked bar charts for part-to-whole comparisons
Trend Charts
- Line charts for time series
- Area charts for cumulative trends
- Sparklines for inline trends
Distribution Charts
- Histograms for frequency distribution
- Box plots for statistical distribution
- Violin plots for distribution shape
Relationship Charts
- Scatter plots for correlations
- Bubble charts for 3D relationships
- Heatmaps for matrix relationships
Composition Charts
- Pie charts for simple part-to-whole
- Stacked area charts for trends over time
- Treemaps for hierarchical composition
Notes
- Always label axes and provide units
- Use appropriate scales (linear, logarithmic)
- Consider data-ink ratio (minimize chart junk)
- Test charts with different data ranges
- Provide legends when using multiple series
- Use annotations to highlight key insights
- Export charts in vector formats for publications
- Keep color schemes consistent across related charts
- Consider cultural differences in color meanings
- Validate data before visualization
Quick Install
/plugin add https://github.com/CuriousLearner/devkit/tree/main/chart-generatorCopy and paste this command in Claude Code to install this skill
GitHub 仓库
Related Skills
langchain
MetaLangChain is a framework for building LLM applications using agents, chains, and RAG pipelines. It supports multiple LLM providers, offers 500+ integrations, and includes features like tool calling and memory management. Use it for rapid prototyping and deploying production systems like chatbots, autonomous agents, and question-answering services.
Algorithmic Art Generation
MetaThis skill helps developers create algorithmic art using p5.js, focusing on generative art, computational aesthetics, and interactive visualizations. It automatically activates for topics like "generative art" or "p5.js visualization" and guides you through creating unique algorithms with features like seeded randomness, flow fields, and particle systems. Use it when you need to build reproducible, code-driven artistic patterns.
webapp-testing
TestingThis Claude Skill provides a Playwright-based toolkit for testing local web applications through Python scripts. It enables frontend verification, UI debugging, screenshot capture, and log viewing while managing server lifecycles. Use it for browser automation tasks but run scripts directly rather than reading their source code to avoid context pollution.
requesting-code-review
DesignThis skill dispatches a code-reviewer subagent to analyze code changes against requirements before proceeding. It should be used after completing tasks, implementing major features, or before merging to main. The review helps catch issues early by comparing the current implementation with the original plan.
