Awesome-Agent-Skills-for-Empirical-Research interactive-viz-guide
Interactive data visualization with Plotly, ECharts, and D3
install
source · Clone the upstream repo
git clone https://github.com/brycewang-stanford/Awesome-Agent-Skills-for-Empirical-Research
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/brycewang-stanford/Awesome-Agent-Skills-for-Empirical-Research "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/43-wentorai-research-plugins/skills/analysis/dataviz/interactive-viz-guide" ~/.claude/skills/brycewang-stanford-awesome-agent-skills-for-empirical-research-interactive-viz-g && rm -rf "$T"
manifest:
skills/43-wentorai-research-plugins/skills/analysis/dataviz/interactive-viz-guide/SKILL.mdsource content
Interactive Visualization Guide
Create interactive, publication-ready visualizations using Plotly, ECharts, Altair, and Bokeh for academic papers, presentations, and supplementary materials.
When to Use Interactive Visualizations
| Scenario | Static | Interactive |
|---|---|---|
| Journal PDF figure | Preferred | Not supported |
| Supplementary materials | Optional | Excellent |
| Conference poster (digital) | Common | Increasingly popular |
| Presentation slides | Standard | Engaging |
| Online appendix / project website | Limited | Ideal |
| Exploratory data analysis | Quick | Detailed exploration |
Plotly (Python)
Plotly produces interactive HTML charts with hover tooltips, zoom, pan, and export capabilities.
Scatter Plot with Hover Details
import plotly.express as px import pandas as pd # Example: visualize paper citations vs. year df = pd.DataFrame({ "title": ["Paper A", "Paper B", "Paper C", "Paper D", "Paper E"], "year": [2019, 2020, 2021, 2022, 2023], "citations": [150, 320, 89, 450, 210], "field": ["NLP", "CV", "NLP", "RL", "CV"], "venue": ["ACL", "CVPR", "EMNLP", "NeurIPS", "ICCV"] }) fig = px.scatter( df, x="year", y="citations", color="field", size="citations", hover_data=["title", "venue"], title="Citation Counts by Year and Field", labels={"citations": "Citation Count", "year": "Publication Year"} ) fig.update_layout( template="plotly_white", font=dict(size=14), width=800, height=500 ) fig.write_html("citations_interactive.html") fig.show()
Grouped Bar Chart
import plotly.graph_objects as go methods = ["Baseline", "Method A", "Method B", "Ours"] accuracy = [82.1, 85.3, 87.0, 89.4] f1_score = [79.8, 83.1, 85.2, 87.9] fig = go.Figure(data=[ go.Bar(name="Accuracy", x=methods, y=accuracy, text=[f"{v}%" for v in accuracy], textposition="auto"), go.Bar(name="F1 Score", x=methods, y=f1_score, text=[f"{v}%" for v in f1_score], textposition="auto") ]) fig.update_layout( barmode="group", title="Model Performance Comparison", yaxis_title="Score (%)", yaxis_range=[70, 95], template="plotly_white" ) fig.write_html("comparison.html")
Heatmap (Confusion Matrix)
import plotly.figure_factory as ff import numpy as np z = [[85, 5, 3, 7], [4, 90, 2, 4], [6, 3, 88, 3], [5, 2, 7, 86]] labels = ["Class A", "Class B", "Class C", "Class D"] fig = ff.create_annotated_heatmap( z, x=labels, y=labels, colorscale="Blues", showscale=True ) fig.update_layout( title="Confusion Matrix", xaxis_title="Predicted", yaxis_title="Actual" ) fig.write_html("confusion_matrix.html")
Altair (Python - Declarative)
Altair uses Vega-Lite grammar for concise, declarative visualization.
import altair as alt import pandas as pd # Interactive scatter with selection df = pd.DataFrame({ "x": range(100), "y": [v**2 + 10 for v in range(100)], "category": ["A" if i % 3 == 0 else "B" if i % 3 == 1 else "C" for i in range(100)] }) selection = alt.selection_point(fields=["category"], bind="legend") chart = alt.Chart(df).mark_circle(size=60).encode( x="x:Q", y="y:Q", color="category:N", opacity=alt.condition(selection, alt.value(1), alt.value(0.2)), tooltip=["x", "y", "category"] ).add_params( selection ).properties( width=600, height=400, title="Interactive Scatter with Legend Selection" ).interactive() # Enable zoom/pan chart.save("altair_scatter.html")
ECharts (JavaScript)
Apache ECharts is a powerful JavaScript charting library ideal for web dashboards and complex visualizations.
<!DOCTYPE html> <html> <head> <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script> </head> <body> <div id="chart" style="width: 800px; height: 500px;"></div> <script> const chart = echarts.init(document.getElementById('chart')); const option = { title: { text: 'Research Output by Year', left: 'center' }, tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } }, legend: { data: ['Papers', 'Citations'], top: 30 }, xAxis: { type: 'category', data: ['2019', '2020', '2021', '2022', '2023'] }, yAxis: [ { type: 'value', name: 'Papers' }, { type: 'value', name: 'Citations' } ], series: [ { name: 'Papers', type: 'bar', data: [12, 15, 18, 22, 28], itemStyle: { color: '#3B82F6' } }, { name: 'Citations', type: 'line', yAxisIndex: 1, data: [45, 120, 280, 450, 680], itemStyle: { color: '#EF4444' }, smooth: true } ], dataZoom: [{ type: 'slider', start: 0, end: 100 }] }; chart.setOption(option); window.addEventListener('resize', () => chart.resize()); </script> </body> </html>
Network Visualization
Plotly Network Graph
import plotly.graph_objects as go import networkx as nx # Create a citation network G = nx.karate_club_graph() pos = nx.spring_layout(G, seed=42) # Edge traces edge_x, edge_y = [], [] for edge in G.edges(): x0, y0 = pos[edge[0]] x1, y1 = pos[edge[1]] edge_x.extend([x0, x1, None]) edge_y.extend([y0, y1, None]) edge_trace = go.Scatter(x=edge_x, y=edge_y, mode="lines", line=dict(width=0.5, color="#888"), hoverinfo="none") # Node traces node_x = [pos[n][0] for n in G.nodes()] node_y = [pos[n][1] for n in G.nodes()] node_degree = [G.degree(n) for n in G.nodes()] node_trace = go.Scatter( x=node_x, y=node_y, mode="markers", marker=dict(size=[d*3 for d in node_degree], color=node_degree, colorscale="Viridis", showscale=True, colorbar=dict(title="Connections")), text=[f"Node {n}: {G.degree(n)} connections" for n in G.nodes()], hoverinfo="text" ) fig = go.Figure(data=[edge_trace, node_trace], layout=go.Layout(title="Citation Network", showlegend=False, xaxis=dict(showgrid=False, zeroline=False, showticklabels=False), yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))) fig.write_html("network.html")
Exporting for Publication
Static Export from Plotly
# Export as high-res static image for journals fig.write_image("figure.pdf", width=1200, height=800, scale=2) # Vector PDF fig.write_image("figure.png", width=1200, height=800, scale=3) # 300 DPI PNG fig.write_image("figure.svg", width=1200, height=800) # Vector SVG # Requires: pip install kaleido
Embedding in Jupyter Notebooks
# Plotly renders natively in Jupyter fig.show() # For Altair in Jupyter chart # Just display the chart object # For ECharts in Jupyter, use pyecharts from pyecharts.charts import Bar from pyecharts import options as opts bar = (Bar() .add_xaxis(["2019", "2020", "2021", "2022", "2023"]) .add_yaxis("Papers", [12, 15, 18, 22, 28]) .set_global_opts(title_opts=opts.TitleOpts(title="Research Output"))) bar.render_notebook()
Best Practices
- Start with a static version: Ensure your visualization works as a static figure first; interactivity is an enhancement, not a replacement.
- Meaningful tooltips: Show relevant context on hover (paper title, exact values, metadata), not just coordinates.
- Responsive design: Use percentage-based sizing or
for ECharts.window.addEventListener('resize') - Accessibility: Provide text alternatives, use colorblind-friendly palettes, and ensure keyboard navigation.
- Performance: For datasets over 10,000 points, use WebGL renderers (Plotly's
, Deck.gl) or server-side aggregation.scattergl - Reproducibility: Save the data alongside the visualization so others can recreate it.