All examples
Visualization

Explore a Boulder bicycle count story

Filter an illustrative Boulder week by inclusive dates and multiple sites across an offline map, period totals and daily trends.

plot_boulder_story.aner
// Development example: requires the matching chart-enabled native runtime.
// Every count and coordinate below is invented for teaching, for October 12-18, 2026.
// Names suggest Boulder-area settings, not real monitoring stations.
import aner.plot
import aner.geo

// Mon Oct 12 through Sun Oct 18, 2026: one invented teaching week.
let days = List(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0)
let creekDaily = List(400.0, 420.0, 440.0, 460.0, 480.0, 840.0, 920.0)
let pearlDaily = List(450.0, 475.0, 500.0, 525.0, 550.0, 600.0, 650.0)
let campusDaily = List(650.0, 675.0, 700.0, 725.0, 750.0, 420.0, 420.0)
let northDaily = List(220.0, 235.0, 250.0, 265.0, 280.0, 350.0, 400.0)
let eastDaily = List(320.0, 335.0, 350.0, 365.0, 380.0, 315.0, 315.0)
let chautauquaDaily = List(180.0, 190.0, 200.0, 210.0, 220.0, 500.0, 540.0)
let boulderTheme = plot.theme("light").palette(List("#0F766E", "#B45309", "#6366A0", "#A43F62", "#2563A6", "#6C7830"))

// No map pack: all six daily series share fixed axes and the same site IDs.
let boulderTrend = plot.line(x: days, y: creekDaily)
    .add_line(x: days, y: campusDaily, name: "Campus")
    .add_line(x: days, y: pearlDaily, name: "Pearl")
    .add_line(x: days, y: northDaily, name: "North")
    .add_line(x: days, y: eastDaily, name: "East")
    .add_line(x: days, y: chautauquaDaily, name: "Chautauqua")
    .link(group: "boulder-sites", ids: List("Creek", "Campus", "Pearl", "North", "East", "Chautauqua"))
    .title("Creek rises on weekends; Campus peaks on weekdays")
    .labels(x: "Day (1=Mon, 2=Tue, 3=Wed, 4=Thu, 5=Fri, 6=Sat, 7=Sun)",
        y: "Invented bicycle count per day")
    .annotate(x: 6.0, y: 840.0, text: "Creek")
    .annotate(x: 6.0, y: 420.0, text: "Campus")
    .caption("Synthetic week, Oct 12-18 2026. Select a site across all views. Counts are invented, not observed bicycle traffic.")
    .theme(boulderTheme)
    .size(width: 1000, height: 640)
boulderTrend.show()

// No map pack: totals equal the sum of all seven daily counts above.
// Sort the categories by total to make comparisons immediate.
let rankedSites = List("Campus", "Creek", "Pearl", "East", "Chautauqua", "North")
let rankedTotals = List(4340.0, 3960.0, 3750.0, 2380.0, 2040.0, 2000.0)
let boulderComparison = plot.bar(labels: rankedSites, values: rankedTotals)
    .link(group: "boulder-sites", ids: rankedSites)
    .title("Campus has the highest invented weekly bicycle count")
    .labels(x: "Illustrative Boulder-area site", y: "Invented bicycle count across seven days")
    .annotate(x: 0.0, y: 4340.0, text: "4,340")
    .annotate(x: 1.0, y: 3960.0, text: "3,960")
    .annotate(x: 2.0, y: 3750.0, text: "3,750")
    .annotate(x: 3.0, y: 2380.0, text: "2,380")
    .annotate(x: 4.0, y: 2040.0, text: "2,040")
    .annotate(x: 5.0, y: 2000.0, text: "2,000")
    .caption("Synthetic seven-day totals, Oct 12-18 2026. Sites are sorted by count. No municipal or observed traffic data.")
    .theme(boulderTheme)
    .size(width: 1000, height: 640)
boulderComparison.show()

// Optional final chart: only the usa.co pack is needed.
// These approximate Boulder-area coordinates do not identify monitoring stations.
let siteNames = List("Creek", "Pearl", "Campus", "North", "East", "Chautauqua")
let sitePositions = List(
    geo.position(longitude: -105.280, latitude: 40.010),
    geo.position(longitude: -105.277, latitude: 40.018),
    geo.position(longitude: -105.264, latitude: 40.006),
    geo.position(longitude: -105.269, latitude: 40.051),
    geo.position(longitude: -105.231, latitude: 40.017),
    geo.position(longitude: -105.292, latitude: 39.997))
let weeklyTotals = List(3960.0, 3750.0, 4340.0, 2000.0, 2380.0, 2040.0)
// Compare daily means, not a two-day total against a five-day total:
// 100 * (((Sat + Sun) / 2) / ((Mon + Tue + Wed + Thu + Fri) / 5) - 1).
let weekendUplift = List(100.0, 25.0, -40.0, 50.0, -10.0, 160.0)
let boulderMapTheme = plot.theme("light").palette(List("#DDEFF0", "#74B9C1", "#0F6578"))

// Empty region joins leave boundary context neutral: N/A means no area-level measure.
let boulderMap = plot.map("usa.co.places", keys: List(), values: List())
    .add_points(positions: sitePositions, values: weekendUplift, labels: siteNames)
    .point_sizes(values: weeklyTotals, max_radius: 13.0)
    .point_labels("avoid")
    .link(group: "boulder-sites", ids: siteNames)
    .extent(west: -105.34, south: 39.96, east: -105.20, north: 40.09)
    .projection("lambert_azimuthal_equal_area")
    .title("Weekend patterns differ across six illustrative Boulder sites")
    .caption("Invented sites/counts. Color = weekend daily uplift (%); area = week total. Census 2025 context; no region measure.")
    .theme(boulderMapTheme)
    .size(width: 1000, height: 640)
boulderMap.show()

Run step by step in VS Code.

The notebook separates observations and chart construction into cells. It opens with empty outputs and shared variables. Map cells state which optional local packs they need.

  1. Install a compatible native Aner executable and VS Code extension using the editor guide. Chart construction and interactive geographic navigation require the matching development runtime and editor.
  2. Download the .anernb notebook and open it in your VS Code project. If it appears as JSON, choose Reopen Editor With… → Aner Notebook.
  3. Select the Aner — notebook kernel and keep Shared variables active. Run code cells from top to bottom, or choose Run All. Later cells reuse observations and chart values from earlier cells. Run cells that need no pack before trying the optional geographic map.
  4. Read the figures below their producing cells. In geographic outputs, drag to pan and use the zoom controls to reveal crowded labels. Static SVG exports retain the initial view. Source observations, units and limitations remain in each caption.

After changing an earlier cell, rerun its dependent cells. Use Aner: Restart Notebook Session, then Run All, for a clean experiment. Saved outputs are historical; reopening the file starts without live variables. The notebook guide explains session state, inspection, and runtime controls.

Make it your experiment.

With a compatible development runtime installed, save this program as examples/plot_boulder_story.aner inside a folder for your experiment. Open a terminal in that folder, then check and run the program.

Terminal
aner check examples/plot_boulder_story.aner
aner run examples/plot_boulder_story.aner

The aner command must be on your PATH. Follow the installation guide if your terminal cannot find it.

Requires a chart enabled native Aner development runtime and a matching VS Code extension for notebook display and interactive geographic navigation. Aner Plot awaits a binary release and is not included in the published research preview. Development packages are not available on this website. Copy the required matching .anermap files to the computer and install them locally. Only the final map needs the usa.co pack; the daily line and site comparison need no map pack. All observations are included, and execution requires no network, credentials or external service. The website shows static native SVG figures; pan and zoom run in the compatible local notebook renderer.

Map pack status
aner maps list
aner maps path

Observations are synthetic teaching inputs. Geographic context comes from optional offline boundary packs and does not add street detail or establish observed traffic conditions.

Read the chart and map contracts
Install Aner