{"spec_id":"bar-permutation-importance","library":"echarts","language":"javascript","code":"// anyplot.ai\n// bar-permutation-importance: Permutation Feature Importance Plot\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 90/100 | Created: 2026-08-26\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Permutation importance for a random forest predicting house sale price.\n// Ordered highest → lowest, then reversed so ECharts (which stacks category\n// entries bottom-to-top) renders the highest importance at the top.\nconst features = [\n  [\"median_income\", 0.352, 0.028],\n  [\"avg_rooms\", 0.184, 0.021],\n  [\"distance_to_coast\", 0.146, 0.019],\n  [\"school_rating\", 0.098, 0.015],\n  [\"latitude\", 0.071, 0.013],\n  [\"longitude\", 0.058, 0.012],\n  [\"house_age\", 0.042, 0.01],\n  [\"population_density\", 0.029, 0.009],\n  [\"crime_rate\", 0.021, 0.008],\n  [\"avg_occupancy\", 0.014, 0.007],\n  [\"num_bathrooms\", 0.009, 0.006],\n  [\"lot_size\", 0.006, 0.006],\n  [\"garage_size\", 0.003, 0.005],\n  [\"year_built\", 0.001, 0.004],\n  [\"parcel_id_checksum\", -0.004, 0.005],\n].reverse();\n\nconst featureNames = features.map((d) => d[0]);\nconst importanceMeans = features.map((d) => d[1]);\nconst maxAbsImportance = Math.max(...importanceMeans.map(Math.abs));\n\n// --- Init --------------------------------------------------------------------\nconst chart = echarts.init(document.getElementById(\"container\"));\n\n// --- Error-bar renderer (±1 SD whiskers around each bar's mean) -------------\nfunction renderErrorBar(params, api) {\n  const idx = params.dataIndex;\n  const mean = api.value(0);\n  const std = api.value(1);\n  const y = api.coord([0, idx])[1];\n  const lowPt = api.coord([mean - std, idx]);\n  const highPt = api.coord([mean + std, idx]);\n  const capHalf = Math.max(6, api.size([0, 1])[1] * 0.16);\n  const style = { stroke: t.inkSoft, lineWidth: 2, lineCap: \"round\" };\n  return {\n    type: \"group\",\n    children: [\n      { type: \"line\", shape: { x1: lowPt[0], y1: y, x2: highPt[0], y2: y }, style },\n      { type: \"line\", shape: { x1: lowPt[0], y1: y - capHalf, x2: lowPt[0], y2: y + capHalf }, style },\n      { type: \"line\", shape: { x1: highPt[0], y1: y - capHalf, x2: highPt[0], y2: y + capHalf }, style },\n    ],\n  };\n}\n\n// --- Option -------------------------------------------------------------------\nchart.setOption({\n  animation: false,\n  backgroundColor: \"transparent\",\n  title: {\n    text: \"bar-permutation-importance · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    textStyle: { color: t.ink, fontSize: 22 },\n  },\n  grid: { left: 260, right: 170, top: 100, bottom: 90 },\n  xAxis: {\n    type: \"value\",\n    name: \"Decrease in Model R² Score\",\n    nameLocation: \"middle\",\n    nameGap: 40,\n    nameTextStyle: { color: t.inkSoft, fontSize: 14 },\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    splitLine: { lineStyle: { color: t.grid } },\n  },\n  yAxis: {\n    type: \"category\",\n    data: featureNames,\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    axisTick: { show: false },\n    splitLine: { show: false },\n  },\n  visualMap: {\n    type: \"continuous\",\n    dimension: 0,\n    seriesIndex: 0,\n    min: -maxAbsImportance,\n    max: maxAbsImportance,\n    calculable: false,\n    orient: \"vertical\",\n    right: 24,\n    top: \"middle\",\n    itemWidth: 20,\n    itemHeight: 320,\n    text: [\"High\\nimportance\", \"Low /\\nnoise\"],\n    textGap: 14,\n    textStyle: { color: t.inkSoft, fontSize: 13 },\n    inRange: { color: t.seq },\n  },\n  series: [\n    {\n      type: \"bar\",\n      name: \"Importance\",\n      data: importanceMeans.map((v) => ({ value: v })),\n      barWidth: \"55%\",\n      z: 2,\n      markLine: {\n        silent: true,\n        symbol: \"none\",\n        lineStyle: { color: t.ink, type: \"dashed\", width: 1.5 },\n        label: { show: false },\n        data: [{ xAxis: 0 }],\n      },\n    },\n    {\n      type: \"custom\",\n      name: \"Variability (±1 SD)\",\n      coordinateSystem: \"cartesian2d\",\n      renderItem: renderErrorBar,\n      data: features.map((d) => [d[1], d[2]]),\n      z: 3,\n    },\n  ],\n});\n"}