This library implements high-level plotting functions for scientific data visualization using a Plotly-inspired API. Create interactive, publication-quality plots with minimal code while maintaining full customization control.
- Scatter Plots: Points, lines, or combined with extensive marker customization
- Line Charts: Time series and continuous data visualization
- Bar Charts: Vertical and horizontal bars with grouping support
- Histograms: Distribution visualization with binning control
- Pie Charts: Proportion visualization with labels and annotations
- Heatmaps: 2D data visualization with color mapping
- 3D Scatter: Three-dimensional data visualization
- Surface Plots: 3D surface rendering for mathematical functions
- Box Plots: Statistical distribution analysis with quartiles
- Violin Plots: Kernel density estimation for distributions
- Contour Plots: Topographical and mathematical contour visualization
- Waterfall Charts: Financial flow and variance analysis
- Candlestick Charts: OHLC stock price visualization
- OHLC Charts: Open-high-low-close time series bars
- Funnel Charts: Conversion and process flow analysis
- Sunburst Charts: Hierarchical data with radial layout
- Treemap Charts: Hierarchical data with nested rectangles
- Sankey Diagrams: Flow and process visualization
- Network Graphs: Node-link relationship visualization
- Radar/Polar Charts: Multi-dimensional comparison
- Parallel Coordinates: High-dimensional data analysis
- 2D Histograms: Bivariate distribution analysis
- Density Plots: Continuous probability distributions
- Ridgeline Plots: Multiple distribution comparison
- Choropleth Maps: Geographic data visualization
- Scatter Mapbox: Location-based scatter plots
- Density Mapbox: Geographic density visualization
- ScatterGeo: Geographic scatter with custom projections
- Radar/Polar Charts: Multi-dimensional comparison
- BarPolar: Polar bar charts (wind roses, compass analysis)
- Zoom & Pan: Mouse-driven plot navigation
- Hover Information: Dynamic data point details
- Legend Control: Show/hide data series
- Export Options: Save as PNG, SVG, or HTML
- Responsive Design: Automatic layout adjustment
import vsl.plot
import vsl.util
// Generate data
x := util.arange(10).map(f64(it))
y := x.map(it * it) // y = x²
// Create plot
mut plt := plot.Plot.new()
plt.scatter(x: x, y: y, mode: 'lines+markers')
plt.layout(title: 'Quadratic Function')
plt.show()!import vsl.plot
dates := ['2024-01', '2024-02', '2024-03', '2024-04']
prices := [100.0, 120.0, 110.0, 130.0]
mut plt := plot.Plot.new()
plt.line(x: dates, y: prices, mode: 'lines+markers')
plt.layout(title: 'Stock Price Trend')
plt.show()!import vsl.plot
data1 := [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
data2 := [2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
mut plt := plot.Plot.new()
plt.box(y: data1, name: 'Dataset A')
plt.box(y: data2, name: 'Dataset B')
plt.layout(title: 'Distribution Comparison')
plt.show()!import vsl.plot
values := [1.0, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0]
mut plt := plot.Plot.new()
plt.violin(y: values, name: 'Distribution')
plt.layout(title: 'Data Distribution Shape')
plt.show()!import vsl.plot
dates := ['2024-01-01', '2024-01-02', '2024-01-03']
open_prices := [100.0, 105.0, 102.0]
high_prices := [110.0, 108.0, 107.0]
low_prices := [95.0, 100.0, 98.0]
close_prices := [105.0, 102.0, 106.0]
mut plt := plot.Plot.new()
plt.candlestick(
x: dates
open: open_prices
high: high_prices
low: low_prices
close: close_prices
)
plt.layout(title: 'Stock Price OHLC')
plt.show()!import vsl.plot
dates := ['2026-03-01', '2026-03-02', '2026-03-03']
open_prices := [100.0, 102.0, 101.0]
high_prices := [104.0, 103.0, 102.0]
low_prices := [99.0, 100.0, 97.0]
close_prices := [103.0, 101.0, 98.0]
mut plt := plot.Plot.new()
plt.ohlc(
x: dates
open: open_prices
high: high_prices
low: low_prices
close: close_prices
)
plt.layout(title: 'OHLC Market Snapshot')
plt.show()!import vsl.plot
mut plt := plot.Plot.new()
plt.table(
header: plot.TableHeader{
values: ['Metric', 'Value']
align: 'left'
}
cells: plot.TableCells{
values: [['MRR', 'Churn'], ['$421k', '2.1%']]
align: 'left'
}
)
plt.layout(title: 'KPI Summary')
plt.show()!import vsl.plot
mut plt := plot.Plot.new()
plt.sunburst(
labels: ['Root', 'A', 'B', 'A1', 'A2', 'B1']
parents: ['', 'Root', 'Root', 'A', 'A', 'B']
values: [100.0, 60.0, 40.0, 30.0, 30.0, 40.0]
)
plt.layout(title: 'Hierarchical Structure')
plt.show()!import vsl.plot
state_codes := ['CA', 'TX', 'NY', 'FL']
population := [39500000.0, 29000000.0, 19500000.0, 21500000.0]
mut plt := plot.Plot.new()
plt.choropleth(
locations: state_codes
z: population
locationmode: 'USA-states'
colorscale: 'Viridis'
)
plt.layout(
title: 'US Population by State'
geo: plot.Geo{
scope: 'usa'
}
)
plt.show()!import vsl.plot
mut plt := plot.Plot.new()
plt.parcoords(
dimensions: [
plot.Dimension{
label: 'Feature 1'
values: [1.0, 2.0, 3.0, 4.0]
},
plot.Dimension{
label: 'Feature 2'
values: [10.0, 20.0, 30.0, 40.0]
},
]
)
plt.layout(title: 'Multi-dimensional Analysis')
plt.show()!import vsl.plot
categories := ['A', 'B', 'C', 'D']
values := [23.0, 45.0, 56.0, 78.0]
mut plt := plot.Plot.new()
plt.bar(x: categories, y: values)
plt.layout(title: 'Category Comparison')
plt.show()!import vsl.plot
// 2D data matrix
z := [[1.0, 20.0, 30.0], [20.0, 1.0, 60.0], [30.0, 60.0, 1.0]]
mut plt := plot.Plot.new()
plt.heatmap(z: z)
plt.layout(title: 'Correlation Matrix')
plt.show()!Colors: Use hex codes (#FF0000), RGB (rgb(255,0,0)), or named colors (red)
Markers: Control size, color, symbol, and opacity
marker:
plot.Marker
{
size: []f64{len: data.len, init: 12.0}
color: ['#FF0000', '#00FF00', '#0000FF']
symbol: 'circle' // Options: circle, square, diamond, triangle, etc.
}Lines: Customize thickness, style, and color
line:
plot.Line
{
color: '#FF0000'
width: 3.0
dash: 'solid' // Options: solid, dash, dot, dashdot
}plt.layout(
title: 'My Plot Title'
xaxis: plot.Axis{
title: plot.AxisTitle{text: 'X-axis Label'}
range: [0.0, 10.0] // Set axis range
}
yaxis: plot.Axis{
title: plot.AxisTitle{text: 'Y-axis Label'}
type: 'log' // Linear or logarithmic scale
}
width: 800
height: 600
)The most important fix for annotation arrows:
// ✅ CORRECT: No unwanted arrows
annotation := plot.Annotation{
text: 'Important Point'
x: 5.0
y: 25.0
showarrow: false // This prevents unwanted arrows!
font: plot.Font{
size: 14
color: '#000000'
}
}
plt.layout(
title: 'Plot with Clean Annotations'
annotations: [annotation]
)font:
plot.Font
{
family: 'Arial, sans-serif'
size: 16
color: '#333333'
}annotation := plot.Annotation
{
text: 'Point with Arrow'
x: 5.0
y: 10.0
showarrow: true
arrowhead: 2 // Arrow style (0-8)
arrowcolor: '#FF0000' // Red arrow color
}Problem: Unwanted arrows show up with annotations
Solution: Always set showarrow: false unless arrows are specifically needed
// ❌ WRONG: May show unwanted arrows
annotation := plot.Annotation{
text: 'My annotation'
x: 1.0
y: 2.0
// Missing showarrow property
}
// ✅ CORRECT: Clean text annotation
annotation := plot.Annotation{
text: 'My annotation'
x: 1.0
y: 2.0
showarrow: false // Explicitly prevent arrows
}Common causes:
- Missing
plt.show()!call - Browser not opening HTML file
- Invalid data format (ensure f64 for numeric data)
Large datasets:
- Consider data sampling for >10,000 points
- Use appropriate plot types (heatmap for dense 2D data)
- Optimize marker sizes and line widths
mut plt := plot.Plot.new()
// First series
plt.scatter(
x: x1, y: y1
name: 'Dataset 1'
marker: plot.Marker{color: ['#FF0000']}
)
// Second series
plt.scatter(
x: x2, y: y2
name: 'Dataset 2'
marker: plot.Marker{color: ['#0000FF']}
)The VSL plot module is actively developed. Subplot functionality is planned for future releases.
The plot module includes convenient functions for common ML visualizations:
import vsl.plot
cm := [[50, 10], [5, 35]]
class_names := ['Negative', 'Positive']
mut plt := plot.plot_confusion_matrix(cm, class_names)
plt.show()!import vsl.plot
import vsl.metrics
// After getting predictions
roc := metrics.roc_curve(y_true, y_score)!
auc := metrics.roc_auc_score(y_true, y_score)!
mut plt := plot.plot_roc_curve(roc.fpr, roc.tpr, auc)
plt.show()!import vsl.plot
import vsl.metrics
pr := metrics.precision_recall_curve(y_true, y_score)!
ap := metrics.average_precision_score(y_true, y_score)!
mut plt := plot.plot_precision_recall_curve(pr.precision, pr.recall, ap)
plt.show()!import vsl.plot
import vsl.la
// Compute correlation matrix
corr := la.correlation_matrix(data)
feature_names := ['Feature A', 'Feature B', 'Feature C']
mut plt := plot.plot_correlation_matrix(corr, feature_names)
plt.show()!import vsl.plot
importances := [0.3, 0.1, 0.4, 0.2]
names := ['Feature A', 'Feature B', 'Feature C', 'Feature D']
mut plt := plot.plot_feature_importance(importances, names, 10) // top 10
plt.show()!import vsl.plot
train_sizes := [100.0, 200.0, 500.0, 1000.0]
train_scores := [0.7, 0.75, 0.82, 0.85]
val_scores := [0.65, 0.72, 0.80, 0.82]
mut plt := plot.plot_learning_curve(train_sizes, train_scores, val_scores)
plt.show()!import vsl.plot
mut plt := plot.plot_residuals(y_pred, residuals)
plt.show()!import vsl.plot
mut plt := plot.plot_actual_vs_predicted(y_true, y_pred)
plt.show()!| Function | Description |
|---|---|
plot_confusion_matrix(cm, class_names) |
Heatmap of confusion matrix |
plot_roc_curve(fpr, tpr, auc) |
ROC curve with AUC in legend |
plot_precision_recall_curve(precision, recall, ap) |
PR curve |
plot_correlation_matrix(corr, feature_names) |
Correlation heatmap |
plot_feature_importance(importances, names, top_n) |
Horizontal bar chart |
plot_learning_curve(sizes, train, val) |
Train vs validation curves |
plot_residuals(y_pred, residuals) |
Residual scatter plot |
plot_actual_vs_predicted(y_true, y_pred) |
Actual vs predicted scatter |
Create beautiful, interactive visualizations with VSL Plot! 🚀
Based on Plotly's graph_objects API design.