{"spec_id":"pdp-basic","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// pdp-basic: Partial Dependence Plot\n// Library: highcharts 12.6.0 | JavaScript 22.23.2\n// Quality: 93/100 | Created: 2026-09-05\n\nconst t = window.ANYPLOT_TOKENS;\nconst BRAND = t.palette[0]; // \"#009E73\" — always first series\n\n// --- Deterministic PRNG (mulberry32) ----------------------------------------\nfunction mulberry32(seed) {\n  return function next() {\n    seed |= 0;\n    seed = (seed + 0x6d2b79f5) | 0;\n    let x = Math.imul(seed ^ (seed >>> 15), 1 | seed);\n    x = (x + Math.imul(x ^ (x >>> 7), 61 | x)) ^ x;\n    return ((x ^ (x >>> 14)) >>> 0) / 4294967296;\n  };\n}\nconst rand = mulberry32(42);\n\n// --- Data --------------------------------------------------------------------\n// Partial dependence of a gradient-boosting model's predicted sale price on\n// living area, averaged over all other features. The effect saturates once\n// extra square footage stops moving the prediction (diminishing returns).\nconst GRID_POINTS = 60;\nconst AREA_MIN = 500;\nconst AREA_MAX = 4000;\nconst livingAreaGrid = Array.from(\n  { length: GRID_POINTS },\n  (_, i) => AREA_MIN + (i * (AREA_MAX - AREA_MIN)) / (GRID_POINTS - 1),\n);\n\nconst midArea = (AREA_MIN + AREA_MAX) / 2;\nconst halfRange = (AREA_MAX - AREA_MIN) / 2;\n\nconst partialDependence = livingAreaGrid.map((area) => {\n  const saturating = 180000 + 95000 * (1 - Math.exp(-area / 1400));\n  const wiggle = 2200 * Math.sin(area / 420) * (rand() * 0.6 + 0.7);\n  return saturating + wiggle;\n});\n\n// Bootstrap-style uncertainty: widest at the sparse edges of the feature range.\nconst ciHalfWidth = livingAreaGrid.map((area) => {\n  const edgeFactor = Math.pow((area - midArea) / halfRange, 2);\n  return 6000 + 30000 * edgeFactor;\n});\nconst ciUpper = partialDependence.map((y, i) => [livingAreaGrid[i], y + ciHalfWidth[i]]);\nconst ciLower = partialDependence.map((y, i) => [livingAreaGrid[i], y - ciHalfWidth[i]]);\nconst pdpLine = partialDependence.map((y, i) => [livingAreaGrid[i], y]);\n\n// Fill anchor safely below every band value so the two area fills only ever\n// meet each other, never the plot's visible floor.\nconst bandFloor = Math.min(...ciLower.map((p) => p[1])) - 40000;\n\n// Pin the axis to the real data range — Highcharts otherwise pulls the\n// autorange down toward the (invisible) fill threshold above, leaving a\n// large dead zone between the band and the rug plot.\nconst yMin = Math.floor((Math.min(...ciLower.map((p) => p[1])) - 5000) / 10000) * 10000;\nconst yMax = Math.ceil((Math.max(...ciUpper.map((p) => p[1])) + 5000) / 10000) * 10000;\n\n// Rug plot: the training data's feature distribution (approx. normal, clipped\n// to the observed range) via Box-Muller on the same seeded PRNG.\nconst RUG_SAMPLES = 160;\nconst trainingAreaSamples = [];\nwhile (trainingAreaSamples.length < RUG_SAMPLES) {\n  const u1 = rand();\n  const u2 = rand();\n  const z = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);\n  const sample = 1900 + z * 550;\n  if (sample >= AREA_MIN && sample <= AREA_MAX) {\n    trainingAreaSamples.push([sample, 1]);\n  }\n}\n\n// --- Chart -------------------------------------------------------------------\nHighcharts.chart(\"container\", {\n  chart: {\n    type: \"spline\",\n    backgroundColor: \"transparent\",\n    animation: false,\n    style: { fontFamily: \"inherit\" },\n  },\n  credits: { enabled: false },\n  colors: t.palette,\n  title: {\n    text: \"pdp-basic · javascript · highcharts · anyplot.ai\",\n    style: { color: t.ink, fontSize: \"22px\", fontWeight: \"600\" },\n  },\n  subtitle: {\n    text: \"Gradient-boosting model · predicted sale price vs. living area · shaded band = bootstrap 90% CI\",\n    style: { color: t.inkSoft, fontSize: \"14px\" },\n  },\n  xAxis: {\n    title: { text: \"Living Area (sq ft)\", style: { color: t.inkSoft, fontSize: \"16px\" } },\n    lineColor: t.inkSoft,\n    tickColor: t.inkSoft,\n    gridLineWidth: 0,\n    labels: { style: { color: t.inkSoft, fontSize: \"14px\" } },\n    min: AREA_MIN,\n    max: AREA_MAX,\n  },\n  yAxis: [\n    {\n      top: \"0%\",\n      height: \"82%\",\n      title: {\n        text: \"Predicted Sale Price ($)\",\n        style: { color: t.inkSoft, fontSize: \"16px\" },\n      },\n      lineColor: t.inkSoft,\n      tickColor: t.inkSoft,\n      gridLineColor: t.grid,\n      labels: {\n        style: { color: t.inkSoft, fontSize: \"14px\" },\n        format: \"${value:,.0f}\",\n      },\n      min: yMin,\n      max: yMax,\n    },\n    {\n      top: \"88%\",\n      height: \"12%\",\n      min: 0,\n      max: 1,\n      visible: false,\n    },\n  ],\n  legend: {\n    itemStyle: { color: t.inkSoft, fontSize: \"14px\" },\n    itemHoverStyle: { color: t.ink },\n  },\n  plotOptions: {\n    series: { animation: false },\n  },\n  tooltip: { enabled: false },\n  series: [\n    {\n      type: \"area\",\n      name: \"90% confidence interval\",\n      data: ciUpper,\n      threshold: bandFloor,\n      lineWidth: 0,\n      fillColor: Highcharts.color(BRAND).setOpacity(0.18).get(),\n      marker: { enabled: false },\n      enableMouseTracking: false,\n    },\n    {\n      type: \"area\",\n      name: \"ci-erase\",\n      data: ciLower,\n      threshold: bandFloor,\n      lineWidth: 0,\n      fillColor: t.pageBg,\n      marker: { enabled: false },\n      enableMouseTracking: false,\n      showInLegend: false,\n    },\n    {\n      type: \"column\",\n      name: \"Training data distribution\",\n      yAxis: 1,\n      data: trainingAreaSamples,\n      color: t.inkSoft,\n      opacity: 0.55,\n      pointWidth: 2,\n      borderWidth: 0,\n      groupPadding: 0,\n      pointPadding: 0,\n      enableMouseTracking: false,\n    },\n    {\n      type: \"spline\",\n      name: \"Partial dependence\",\n      data: pdpLine,\n      color: BRAND,\n      lineWidth: 3,\n      marker: { enabled: false },\n    },\n  ],\n});\n"}