{"version":"2026-09-04","count":31,"items":[{"id":"local-sample","chartTypeZh":"时序拟合与预测区间","builder":"build_sample_figure","builderSignature":"build_sample_figure(mode: str)","sourceRelativePath":"绘图样式/生成样例图.py","inputAdaptation":"将 sample_data() 改为已验证的历史时间/观测/拟合值及未来时间/点预测/上下界；历史和预测区段分开。","scientificBoundary":"当前区间来自构造残差及特定正态独立同方差近似；不能沿用其 95% 名称或数值至其他模型。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple","confidence-band"],"title":"月销量拟合与预测示例","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成样例图 import build_sample_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_sample_figure('paper')[0]\nsave_fig(fig, '月销量拟合与预测示例', '样例', mode='paper', sample=True)","source":"def build_sample_figure(mode: str):\n    \"\"\"构造一张历史 1–9 月、预测 10–12 月的固定示例图。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    data = sample_data()\n    fig, ax = new_fig(width=\"full\", ratio=0.618, mode=mode)\n\n    interval = ax.fill_between(\n        data[\"interval_month\"],\n        data[\"lower\"],\n        data[\"upper\"],\n        color=SEMANTIC[\"预测区间填充\"],\n        alpha=0.22,\n        label=INTERVAL_NAME,\n        linewidth=0,\n        zorder=ZORDER[\"区间\"],\n    )\n    history_line = ax.plot(\n        data[\"actual_month\"],\n        data[\"history_fit\"],\n        color=SEMANTIC[\"主推模型\"],\n        linewidth=1.8 if mode == \"paper\" else 2.0,\n        linestyle=\"-\",\n        marker=None,\n        label=\"历史拟合\",\n        zorder=ZORDER[\"主线\"],\n    )[0]\n    forecast_line = ax.plot(\n        data[\"forecast_line_month\"],\n        data[\"forecast_line\"],\n        color=SEMANTIC[\"主推模型\"],\n        linewidth=1.8 if mode == \"paper\" else 2.0,\n        linestyle=(0, (4, 2.4)),\n        marker=None,\n        label=\"未来预测\",\n        zorder=ZORDER[\"主线\"],\n    )[0]\n    actual = plot_raw_points(\n        ax,\n        data[\"actual_month\"],\n        data[\"actual\"],\n        reference_area_pt2=24.0 if mode == \"paper\" else 38.0,\n        color=SEMANTIC[\"实测数据\"],\n        marker=\"o\",\n        label=\"实际销量\",\n    )\n\n    if mode == \"show\":\n        ax.set_title(\"月销量拟合与预测示例\")\n    ax.set_xlabel(\"时间（月）\")\n    ax.set_ylabel(\"销量（件）\")\n    ax.set_xticks(data[\"month\"])\n    plotted_y = np.concatenate(\n        (\n            data[\"actual\"],\n            data[\"history_fit\"],\n            data[\"forecast\"],\n            data[\"lower\"],\n            data[\"upper\"],\n        )\n    )\n    # 第一次按数据确定坐标，为分期标签和峰值标注提供稳定的变换基准。\n    apply_data_limits(ax, data[\"month\"], plotted_y)\n    divider = forecast_divider_position(\n        data[\"actual_month\"],\n        data[\"forecast_month\"],\n    )\n    add_forecast_divider(\n        ax,\n        data[\"actual_month\"],\n        data[\"forecast_month\"],\n    )\n    legend = ax.legend(\n        handles=[actual, history_line, forecast_line, interval],\n        labels=[\"实际销量\", \"历史拟合\", \"未来预测\", INTERVAL_NAME],\n        loc=\"upper left\",\n        ncols=1,\n        frameon=False,\n        facecolor=\"none\",\n        edgecolor=\"none\",\n        handlelength=1.7,\n        handletextpad=0.45,\n        labelspacing=0.28,\n        borderpad=0.12,\n        columnspacing=0.8,\n        markerscale=0.78,\n    )\n    forecast_peak = int(np.argmax(data[\"forecast\"]))\n    peak_month = float(data[\"forecast_month\"][forecast_peak])\n    peak_value = float(data[\"forecast\"][forecast_peak])\n    # 不强制文字压在区间带上方（min_text_y）：「预测期」阶段标签恰在预测区\n    # 中央上方，与带顶同高的文字必与其重叠（实测）；放开纵向让避让机制把\n    # 文字安置到分界线右侧的空白区，箭头仍准确指向峰值点\n    peak_annotation = mark_point(\n        ax,\n        peak_month,\n        peak_value,\n        f\"预测峰值：{peak_value:.0f} 件\",\n        time_label=f\"{peak_month:.0f}月\",\n        allowed_x_range=(divider, float(ax.get_xlim()[1])),\n    )\n    # 第二次只根据峰值附近文字的真实占位抬升顶部，避免固定大留白。\n    apply_data_limits(\n        ax,\n        data[\"month\"],\n        plotted_y,\n        top_artists=[legend, *ax._cumcm_stage_labels, peak_annotation],\n        top_focus_x=peak_month,\n    )\n    ax._cumcm_peak = {  # type: ignore[attr-defined]\n        \"month\": peak_month,\n        \"value\": peak_value,\n    }\n    return fig, ax","preview":"assets/workflow/local-sample.png","helpers":[{"name":"add_forecast_divider","signature":"add_forecast_divider(ax, history_x: Sequence[float] | np.ndarray, forecast_x: Sequence[float] | np.ndarray, left_label: str='历史期', right_label: str='预测期')"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_raw_points","signature":"plot_raw_points(ax, x: Sequence[float] | np.ndarray, y: Sequence[float] | np.ndarray, *, reference_area_pt2: float | None=None, density_count: int | None=None, color: Any | None=None, c: Sequence[float] | np.ndarray | None=None, cmap: Any | None=None, norm: Any | None=None, marker: str='o', edgecolor: Any=None, label: str | None=None, zorder: float | None=None)"}]},{"id":"local-grid-sample","chartTypeZh":"时序预测与残差组图","builder":"build_grid_sample_figure","builderSignature":"build_grid_sample_figure(mode: str)","sourceRelativePath":"绘图样式/生成样例图.py","inputAdaptation":"传入同一来源的观测、拟合、预测及区间；残差定义与训练/验证区间一致。","scientificBoundary":"保留原始残差，不能通过绘图重新拟合或把样例的近似区间当成通用预测区间。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple","confidence-band","scatter-simple"],"title":"销量预测与残差诊断","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成样例图 import build_grid_sample_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_grid_sample_figure('paper')[0]\nsave_fig(fig, '销量预测与残差诊断', '样例', mode='paper', sample=True)","source":"def build_grid_sample_figure(mode: str):\n    \"\"\"用同一份示例数据构造主结论与残差诊断组图。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    data = sample_data()\n    fig, axes = new_grid(1, 2, width=\"full\", mode=mode, share=\"x\", hero=0)\n    main_ax, residual_ax = axes[0]\n\n    interval = main_ax.fill_between(\n        data[\"interval_month\"],\n        data[\"lower\"],\n        data[\"upper\"],\n        color=SEMANTIC[\"预测区间填充\"],\n        alpha=0.22,\n        label=INTERVAL_NAME,\n        linewidth=0,\n        zorder=ZORDER[\"区间\"],\n    )\n    history_line = main_ax.plot(\n        data[\"actual_month\"],\n        data[\"history_fit\"],\n        color=SEMANTIC[\"主推模型\"],\n        linewidth=1.8 if mode == \"paper\" else 2.0,\n        linestyle=\"-\",\n        marker=None,\n        label=\"历史拟合\",\n        zorder=ZORDER[\"主线\"],\n    )[0]\n    forecast_line = main_ax.plot(\n        data[\"forecast_line_month\"],\n        data[\"forecast_line\"],\n        color=SEMANTIC[\"主推模型\"],\n        linewidth=1.8 if mode == \"paper\" else 2.0,\n        linestyle=(0, (4, 2.4)),\n        marker=None,\n        label=\"未来预测\",\n        zorder=ZORDER[\"主线\"],\n    )[0]\n    actual = plot_raw_points(\n        main_ax,\n        data[\"actual_month\"],\n        data[\"actual\"],\n        reference_area_pt2=19.0 if mode == \"paper\" else 30.0,\n        color=SEMANTIC[\"实测数据\"],\n        marker=\"o\",\n        label=\"实际销量\",\n    )\n    main_ax.set_xlabel(\"时间（月）\")\n    main_ax.set_ylabel(\"销量（件）\")\n    grid_ticks = data[\"month\"][::2]\n    main_ax.set_xticks(grid_ticks)\n    main_y = np.concatenate(\n        (\n            data[\"actual\"],\n            data[\"history_fit\"],\n            data[\"forecast\"],\n            data[\"lower\"],\n            data[\"upper\"],\n        )\n    )\n    apply_data_limits(main_ax, data[\"month\"], main_y)\n    add_forecast_divider(\n        main_ax,\n        data[\"actual_month\"],\n        data[\"forecast_month\"],\n    )\n    main_ax.legend(\n        handles=[actual, history_line, forecast_line, interval],\n        labels=[\"实际销量\", \"历史拟合\", \"未来预测\", INTERVAL_NAME],\n        loc=\"upper left\",\n        bbox_to_anchor=(0.02, 0.88),\n        ncols=1,\n        frameon=False,\n        facecolor=\"none\",\n        edgecolor=\"none\",\n        handlelength=1.4,\n        handletextpad=0.35,\n        labelspacing=0.22,\n        borderpad=0.08,\n        markerscale=0.72,\n    )\n\n    residual_ax.axhline(\n        0.0,\n        color=SEMANTIC[\"分期线\"],\n        linewidth=0.85,\n        linestyle=(0, (3, 2.4)),\n        zorder=ZORDER[\"分期\"],\n    )\n    plot_raw_points(\n        residual_ax,\n        data[\"actual_month\"],\n        data[\"residual\"],\n        reference_area_pt2=22.0 if mode == \"paper\" else 34.0,\n        color=SEMANTIC[\"对照方案\"],\n        marker=\"o\",\n    )\n    residual_ax.set_xlabel(\"时间（月）\")\n    residual_ax.set_ylabel(\"残差（件）\")\n    residual_ax.set_xticks(grid_ticks)\n    apply_data_limits(residual_ax, data[\"month\"], data[\"residual\"])\n\n    if mode == \"show\":\n        main_ax.set_title(\"拟合与预测\", fontsize=12.0, pad=7.0)\n        residual_ax.set_title(\"历史残差\", fontsize=12.0, pad=7.0)\n    fig._cumcm_suggested_caption = GRID_SUGGESTED_CAPTION  # type: ignore[attr-defined]\n    return fig, axes","preview":"assets/workflow/local-grid-sample.png","helpers":[{"name":"add_forecast_divider","signature":"add_forecast_divider(ax, history_x: Sequence[float] | np.ndarray, forecast_x: Sequence[float] | np.ndarray, left_label: str='历史期', right_label: str='预测期')"},{"name":"new_grid","signature":"new_grid(nrows: int, ncols: int, width: Literal['full', 'half']='full', mode: Mode='paper', share: ShareMode=None, hero: int | tuple[int, int] | None=None, ratio: float | None=None)"},{"name":"plot_raw_points","signature":"plot_raw_points(ax, x: Sequence[float] | np.ndarray, y: Sequence[float] | np.ndarray, *, reference_area_pt2: float | None=None, density_count: int | None=None, color: Any | None=None, c: Sequence[float] | np.ndarray | None=None, cmap: Any | None=None, norm: Any | None=None, marker: str='o', edgecolor: Any=None, label: str | None=None, zorder: float | None=None)"}]},{"id":"local-distribution-combo","chartTypeZh":"雨云图（半小提琴、箱线、原始点）","builder":"build_distribution_combo_figure","builderSignature":"build_distribution_combo_figure(mode: str)","sourceRelativePath":"绘图样式/生成样例图.py","inputAdaptation":"以分组一维原始样本 groups 和组名 labels 调用 plot_raincloud；保留样本量与单位。","scientificBoundary":"样本过少不适合估计平滑密度；不自动推断显著性，不删除离群点。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["boxplot-light-velocity"],"title":"候选方案收益分布","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成样例图 import build_distribution_combo_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_distribution_combo_figure('paper')[0]\nsave_fig(fig, '候选方案收益分布', '样例', mode='paper', sample=True)","source":"def build_distribution_combo_figure(mode: str):\n    \"\"\"构造一个坐标轴内叠加半小提琴、箱线与原始点的组合图。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    groups, labels = distribution_combo_data()\n    fig, ax = new_fig(width=\"full\", ratio=0.48, mode=mode)\n    plot_raincloud(ax, groups, labels, seed=20260824)\n    ax.set_xlabel(\"候选方案\")\n    ax.set_ylabel(\"综合收益（分）\")\n    if mode == \"show\":\n        ax.set_title(\"候选方案收益分布\", fontsize=12.0, pad=7.0)\n    fig._cumcm_suggested_caption = RAINCLOUD_SUGGESTED_CAPTION  # type: ignore[attr-defined]\n    return fig, ax","preview":"assets/workflow/local-distribution-combo.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_raincloud","signature":"plot_raincloud(ax, groups: Sequence[Sequence[float] | np.ndarray], labels: Sequence[str], *, seed: int=20260824, violin_width: float=0.72)"}]},{"id":"local-scientific-mosaic","chartTypeZh":"方案前沿与稳健性复合组图","builder":"build_scientific_mosaic_figure","builderSignature":"build_scientific_mosaic_figure(mode: str)","sourceRelativePath":"绘图样式/生成样例图.py","inputAdaptation":"将 scientific_mosaic_data() 中候选方案、前沿、敏感性曲线和影响矩阵改为同一正式运行结果，登记主图与各诊断角色。","scientificBoundary":"本配方是构造数据的版式组合，不是优化算法；不同图层必须各有独立证据作用。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["scatter-simple","heatmap-cartesian","line-simple"],"title":"方案前沿与稳健性诊断","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成样例图 import build_scientific_mosaic_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_scientific_mosaic_figure('paper')[0]\nsave_fig(fig, '方案前沿与稳健性诊断', '样例', mode='paper', sample=True)","source":"def build_scientific_mosaic_figure(mode: str):\n    \"\"\"构造主次面积、连续色标和混合矢量导出的科研组图样例。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    data = scientific_mosaic_data()\n    fig, axes = new_mosaic(\n        [[\"frontier\", \"sensitivity\"], [\"frontier\", \"influence\"]],\n        panel_order=(\"frontier\", \"sensitivity\", \"influence\"),\n        width=\"full\",\n        ratio=0.60,\n        mode=mode,\n        hero=\"frontier\",\n        width_ratios=(1.38, 1.0),\n        height_ratios=(0.90, 1.10),\n    )\n    frontier_ax = axes[\"frontier\"]\n    sensitivity_ax = axes[\"sensitivity\"]\n    influence_ax = axes[\"influence\"]\n    chinese_family = fig._cumcm_font_info[\"chinese_family\"]  # type: ignore[attr-defined]\n\n    sequential_cmap, sequential_norm = continuous_scale(\n        data[\"robustness\"], kind=\"sequential\"\n    )\n    candidates = plot_raw_points(\n        frontier_ax,\n        data[\"cost\"],\n        data[\"benefit\"],\n        reference_area_pt2=5.0 if mode == \"paper\" else 7.0,\n        density_count=int(data[\"cost\"].size),\n        c=data[\"robustness\"],\n        cmap=sequential_cmap,\n        norm=sequential_norm,\n        label=\"可行方案\",\n    )\n    frontier_ax.plot(\n        data[\"frontier_cost\"],\n        data[\"frontier_benefit\"],\n        color=SEMANTIC[\"高对比文字\"],\n        linewidth=1.35 if mode == \"paper\" else 1.65,\n        linestyle=\"-\",\n        marker=None,\n        label=\"Pareto 前沿\",\n        zorder=ZORDER[\"主线\"],\n    )\n    frontier_ax.scatter(\n        data[\"compromise_cost\"],\n        data[\"compromise_benefit\"],\n        color=SEMANTIC[\"最优标注\"],\n        edgecolor=SEMANTIC[\"背景\"],\n        linewidth=0.75,\n        marker=\"D\",\n        s=42.0 if mode == \"paper\" else 58.0,\n        label=\"折中方案\",\n        zorder=ZORDER[\"标注\"],\n    )\n    frontier_ax.set_xlabel(\"成本（万元）\")\n    frontier_ax.set_ylabel(\"综合效益（分）\")\n    apply_data_limits(frontier_ax, data[\"cost\"], data[\"benefit\"])\n    frontier_ax.legend(loc=\"lower right\", markerscale=0.85)\n    robustness_cax = frontier_ax.inset_axes((0.12, 0.895, 0.40, 0.018))\n    robustness_cax.set_in_layout(False)\n    robustness_bar = add_continuous_colorbar(\n        fig,\n        candidates,\n        frontier_ax,\n        label=\"鲁棒得分（0–1）\",\n        max_ticks=4,\n        cax=robustness_cax,\n        orientation=\"horizontal\",\n    )\n    robustness_bar.set_label(\n        \"鲁棒得分（0–1）\",\n        fontsize=8.0 if mode == \"paper\" else 10.0,\n        fontfamily=chinese_family,\n        labelpad=2.0,\n    )\n    robustness_bar.ax.xaxis.set_label_position(\"top\")\n    robustness_bar.ax.tick_params(axis=\"x\", length=2.0, pad=1.0)\n\n    # 小面板端点直标采用短名称，完整参数定义留在图注/正文；避免长中文标签\n    # 在同一 x 端点横向贴压，且不引入遮挡数据的图例框。\n    sensitivity_names = (\"需求\", \"资源\", \"惩罚\")\n    sensitivity_lines = plot_line_series(\n        sensitivity_ax,\n        data[\"perturbation\"],\n        data[\"sensitivity\"],\n        sensitivity_names,\n        direct_labels=True,\n        include_markers=True,\n    )\n    sensitivity_ax.axhline(\n        0.0,\n        color=SEMANTIC[\"分期线\"],\n        linewidth=0.8,\n        linestyle=(0, (3, 2.4)),\n        zorder=ZORDER[\"分期\"],\n    )\n    sensitivity_ax.set_xlabel(\"参数扰动（%）\")\n    sensitivity_ax.set_ylabel(\"目标变化（%）\")\n    sensitivity_ax.grid(False)\n    apply_data_limits(\n        sensitivity_ax,\n        data[\"perturbation\"],\n        np.concatenate([line.get_ydata() for line in sensitivity_lines]),\n    )\n\n    matrix, _ = plot_annotated_heatmap(\n        influence_ax,\n        data[\"influence\"],\n        (\"收益\", \"风险\", \"公平\", \"耗时\"),\n        (\"需求\", \"资源\", \"惩罚\", \"初值\"),\n        kind=\"diverging\",\n        center=0.0,\n        value_format=\"+.2f\",\n        x_rotation=24.0,\n    )\n    influence_ax.set_xlabel(\"评价维度\")\n    influence_ax.set_ylabel(\"参数\")\n    add_continuous_colorbar(\n        fig,\n        matrix,\n        influence_ax,\n        label=\"标准化影响\",\n        fraction=0.052,\n        pad=0.028,\n        shrink=0.94,\n    )\n\n    if mode == \"show\":\n        frontier_ax.set_title(\"方案前沿与折中点\", fontsize=12.0, pad=7.0)\n        sensitivity_ax.set_title(\"局部灵敏度\", fontsize=12.0, pad=7.0)\n        influence_ax.set_title(\"参数—指标影响\", fontsize=12.0, pad=7.0)\n    fig._cumcm_suggested_caption = MOSAIC_SUGGESTED_CAPTION  # type: ignore[attr-defined]\n    return fig, axes","preview":"assets/workflow/local-scientific-mosaic.png","helpers":[{"name":"add_continuous_colorbar","signature":"add_continuous_colorbar(fig, mappable: Any, ax, *, label: str, max_ticks: int=5, fraction: float=0.043, pad: float=0.025, shrink: float=1.0, cax: Any | None=None, orientation: Literal['vertical', 'horizontal'] | None=None)"},{"name":"new_mosaic","signature":"new_mosaic(mosaic: str | Sequence[Sequence[str]], *, panel_order: Sequence[str] | None=None, width: Literal['full', 'half']='full', ratio: float=0.72, mode: Mode='paper', share: ShareMode=None, hero: str | None=None, width_ratios: Sequence[float] | None=None, height_ratios: Sequence[float] | None=None)"},{"name":"plot_annotated_heatmap","signature":"plot_annotated_heatmap(ax, values: Sequence[Sequence[float]] | np.ndarray, x_labels: Sequence[str], y_labels: Sequence[str], *, kind: ContinuousKind, center: float=0.0, value_format: str='+.2f', x_rotation: float=0.0, origin: Literal['upper', 'lower']='upper', annotate: bool=True, fontsize: float | None=None, square_cells: bool=False, domain: Sequence[float] | None=None, domain_basis: str='')"},{"name":"plot_line_series","signature":"plot_line_series(ax, x: Sequence[float] | np.ndarray, y_series: Sequence[Sequence[float]] | np.ndarray, labels: Sequence[str], *, direct_labels: bool=True, include_markers: bool=True, ordered_by: Sequence[float] | np.ndarray | None=None, focal_label: str | None=None, linewidth: float | None=None, markersize: float | None=None)"},{"name":"plot_raw_points","signature":"plot_raw_points(ax, x: Sequence[float] | np.ndarray, y: Sequence[float] | np.ndarray, *, reference_area_pt2: float | None=None, density_count: int | None=None, color: Any | None=None, c: Sequence[float] | np.ndarray | None=None, cmap: Any | None=None, norm: Any | None=None, marker: str='o', edgecolor: Any=None, label: str | None=None, zorder: float | None=None)"}]},{"id":"local-bar-line-points","chartTypeZh":"柱、独立基准折线与原始点","builder":"build_bar_line_points_figure","builderSignature":"build_bar_line_points_figure(mode: str)","sourceRelativePath":"绘图样式/生成多样示意图.py","inputAdaptation":"分组原始样本、组名和独立计算的 line_values；通过 line_basis 说明基准来源。","scientificBoundary":"三层同轴同单位，折线不得逐点重复柱高；样例的长期气候基准也是合成值。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple","scatter-simple"],"title":"月降水的水平波动与季节趋势","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成多样示意图 import build_bar_line_points_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_bar_line_points_figure('paper')[0]\nsave_fig(fig, '月降水的水平波动与季节趋势', '样例', mode='paper', sample=True)","source":"def build_bar_line_points_figure(mode: str):\n    \"\"\"构造“汇总柱—独立趋势线—原始观测点”同轴组合图。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    data = monthly_bar_line_point_data()\n    fig, ax = new_fig(width=\"full\", ratio=0.52, mode=mode)\n    recipe = plot_bar_line_points(\n        ax,\n        data[\"groups\"],\n        data[\"labels\"],\n        data[\"climate_normal\"],\n        line_basis=\"独立于近八年样本的三十年逐月气候平均基准\",\n        summary=\"mean\",\n        seed=20260826,\n        bar_label=\"近 8 年月均值\",\n        line_label=\"30 年气候基准\",\n        point_label=\"逐年观测\",\n    )\n    ax.set_xlabel(\"月份\")\n    ax.set_ylabel(\"月降水量（mm）\")\n    ax.legend(\n        handles=(recipe[\"bars\"], recipe[\"line\"], recipe[\"points\"]),\n        labels=(\"近 8 年月均值\", \"30 年气候基准\", \"逐年观测\"),\n        loc=\"upper left\",\n        ncols=3,\n        frameon=False,\n        fontsize=8.0 if mode == \"paper\" else 9.0,\n        handlelength=1.65,\n        handletextpad=0.45,\n        columnspacing=0.9,\n    )\n    if mode == \"show\":\n        ax.set_title(\"月降水的水平、波动与季节趋势\", fontsize=12.0, pad=7.0)\n    fig._cumcm_suggested_caption = (  # type: ignore[attr-defined]\n        \"固定随机种子的合成降水算例。柱高为近 8 年逐月观测均值，半透明小点为\"\n        \"构成该均值的 8 个逐年观测，折线为独立于这 8 年样本的 30 年逐月气候\"\n        \"平均基准；三层共享月份轴和 mm 量纲，分别回答近期水平、年际离散以及\"\n        \"相对长期基准的偏离。所有数值均为示例。\"\n    )\n    return fig, ax, recipe","preview":"assets/workflow/local-bar-line-points.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_bar_line_points","signature":"plot_bar_line_points(ax, groups: Sequence[Sequence[float] | np.ndarray], labels: Sequence[str], line_values: Sequence[float] | np.ndarray, *, line_basis: str, summary: Literal['mean', 'median']='mean', seed: int=20260826, bar_label: str='观测均值', line_label: str='模型趋势', point_label: str='原始观测')"}]},{"id":"local-model-diagnostic","chartTypeZh":"实测预测一致性、残差与 Q-Q 组图","builder":"build_model_diagnostic_figure","builderSignature":"build_model_diagnostic_figure(mode: str)","sourceRelativePath":"绘图样式/生成多样示意图.py","inputAdaptation":"提供对应的 observed/predicted 数组；沿用 plot_observed_vs_predicted、原始残差与 Q-Q 数据生成步骤。","scientificBoundary":"必须区分训练和验证数据；Q-Q 形态不能替代模型外推有效性。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["scatter-simple","line-simple"],"title":"模型预测一致性与残差检验","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成多样示意图 import build_model_diagnostic_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_model_diagnostic_figure('paper')[0]\nsave_fig(fig, '模型预测一致性与残差检验', '样例', mode='paper', sample=True)","source":"def build_model_diagnostic_figure(mode: str):\n    \"\"\"构造一致性、残差结构与 Q--Q 图组成的模型证据组图。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    data = model_diagnostic_data()\n    palette = SHOWCASE_SERIES if mode == \"show\" else SERIES\n    fig, axes = new_mosaic(\n        [[\"agreement\", \"residual\"], [\"agreement\", \"qq\"]],\n        panel_order=(\"agreement\", \"residual\", \"qq\"),\n        width=\"full\",\n        ratio=0.62,\n        mode=mode,\n        hero=\"agreement\",\n        width_ratios=(1.16, 1.0),\n        height_ratios=(1.0, 1.0),\n    )\n    agreement_ax = axes[\"agreement\"]\n    residual_ax = axes[\"residual\"]\n    qq_ax = axes[\"qq\"]\n\n    points, identity, metrics = plot_observed_vs_predicted(\n        agreement_ax,\n        data[\"observed\"],\n        data[\"predicted\"],\n        point_label=\"样本\",\n        identity_label=\"一致线\",\n    )\n    points.set_facecolor(palette[0])\n    agreement_ax.set_xlabel(\"实测负荷（kW）\")\n    agreement_ax.set_ylabel(\"预测负荷（kW）\")\n    agreement_ax.legend(\n        handles=(points, identity),\n        labels=(\"样本\", \"一致线\"),\n        loc=\"upper left\",\n        frameon=False,\n        fontsize=8.0 if mode == \"paper\" else 9.0,\n        markerscale=0.72,\n        handlelength=1.45,\n        labelspacing=0.30,\n    )\n\n    plot_raw_points(\n        residual_ax,\n        data[\"predicted\"],\n        data[\"residual\"],\n        reference_area_pt2=13.0 if mode == \"paper\" else 20.0,\n        density_count=int(data[\"residual\"].size),\n        color=palette[0],\n    )\n    centers, lower, median, upper = _binned_residual_summary(\n        data[\"predicted\"], data[\"residual\"]\n    )\n    residual_ax.fill_between(\n        centers,\n        lower,\n        upper,\n        color=palette[0],\n        alpha=0.16,\n        linewidth=0,\n        label=\"10%–90%分位范围\",\n        zorder=ZORDER[\"区间\"],\n    )\n    residual_ax.plot(\n        centers,\n        median,\n        color=SEMANTIC[\"高对比文字\"],\n        linewidth=1.25 if mode == \"paper\" else 1.65,\n        marker=\"o\",\n        markersize=3.2 if mode == \"paper\" else 4.3,\n        label=\"分箱中位数\",\n        zorder=ZORDER[\"主线\"],\n    )\n    residual_ax.axhline(\n        0.0,\n        color=SEMANTIC[\"分期线\"],\n        linewidth=0.8,\n        linestyle=(0, (3.2, 2.4)),\n        zorder=ZORDER[\"分期\"],\n    )\n    residual_ax.set_xlabel(\"预测负荷（kW）\")\n    residual_ax.set_ylabel(\"预测残差（kW）\")\n    apply_data_limits(\n        residual_ax,\n        data[\"predicted\"],\n        np.concatenate((data[\"residual\"], lower, upper)),\n        x_margin_steps=0.40,\n    )\n\n    standardized = (\n        data[\"residual\"] - np.mean(data[\"residual\"])\n    ) / np.std(data[\"residual\"], ddof=1)\n    sample_quantiles = np.sort(standardized)\n    probabilities = (\n        np.arange(1, sample_quantiles.size + 1, dtype=float) - 0.5\n    ) / sample_quantiles.size\n    normal = NormalDist()\n    theoretical = np.asarray(\n        [normal.inv_cdf(float(value)) for value in probabilities],\n        dtype=float,\n    )\n    plot_raw_points(\n        qq_ax,\n        theoretical,\n        sample_quantiles,\n        reference_area_pt2=12.0 if mode == \"paper\" else 19.0,\n        density_count=int(sample_quantiles.size),\n        color=palette[1],\n    )\n    reference_low = float(min(np.min(theoretical), np.min(sample_quantiles)))\n    reference_high = float(max(np.max(theoretical), np.max(sample_quantiles)))\n    qq_ax.plot(\n        [reference_low, reference_high],\n        [reference_low, reference_high],\n        color=SEMANTIC[\"分期线\"],\n        linewidth=0.85,\n        linestyle=(0, (3.2, 2.4)),\n        zorder=ZORDER[\"分期\"],\n    )\n    qq_ax.set_xlabel(\"理论分位数（z）\")\n    qq_ax.set_ylabel(\"样本分位数（z）\")\n    apply_data_limits(\n        qq_ax,\n        theoretical,\n        sample_quantiles,\n        x_margin_steps=0.40,\n    )\n\n    if mode == \"show\":\n        agreement_ax.set_title(\"一致性\", fontsize=11.0, pad=6.0)\n        residual_ax.set_title(\"残差结构\", fontsize=11.0, pad=6.0)\n        qq_ax.set_title(\"Q–Q 检验\", fontsize=11.0, pad=6.0)\n    fig._cumcm_suggested_caption = (  # type: ignore[attr-defined]\n        \"固定随机种子的合成算例用于演示模型诊断证据链。\"\n        \"(a) 比较实测值与预测值；(b) 叠加原始残差、等频分箱中位数和\"\n        \"10%–90%分位范围；(c) 比较标准化残差与正态理论分位数。\"\n        f\"样本量 n={metrics['n']}，RMSE={metrics['RMSE']:.2f} kW，\"\n        f\"MAE={metrics['MAE']:.2f} kW，R²={metrics['R2']:.3f}。\"\n        \"所有数值均为示例，不代表任何赛题结果。\"\n    )\n    return fig, axes","preview":"assets/workflow/local-model-diagnostic.png","helpers":[{"name":"new_mosaic","signature":"new_mosaic(mosaic: str | Sequence[Sequence[str]], *, panel_order: Sequence[str] | None=None, width: Literal['full', 'half']='full', ratio: float=0.72, mode: Mode='paper', share: ShareMode=None, hero: str | None=None, width_ratios: Sequence[float] | None=None, height_ratios: Sequence[float] | None=None)"},{"name":"plot_observed_vs_predicted","signature":"plot_observed_vs_predicted(ax, observed: Sequence[float] | np.ndarray, predicted: Sequence[float] | np.ndarray, *, point_label: str='样本', identity_label: str='理想一致线', equal_aspect: bool=True)"},{"name":"plot_raw_points","signature":"plot_raw_points(ax, x: Sequence[float] | np.ndarray, y: Sequence[float] | np.ndarray, *, reference_area_pt2: float | None=None, density_count: int | None=None, color: Any | None=None, c: Sequence[float] | np.ndarray | None=None, cmap: Any | None=None, norm: Any | None=None, marker: str='o', edgecolor: Any=None, label: str | None=None, zorder: float | None=None)"}]},{"id":"local-interval-sensitivity","chartTypeZh":"因素点估计与区间图","builder":"build_interval_sensitivity_figure","builderSignature":"build_interval_sensitivity_figure(mode: str)","sourceRelativePath":"绘图样式/生成多样示意图.py","inputAdaptation":"以标签、点估计、上下界调用 plot_interval_estimates，并声明 interval_label/interval_basis。","scientificBoundary":"现样例为构造蒙特卡洛情景的 5%–95% 分位范围；不是统计显著性或默认置信区间。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["custom-error-scatter"],"title":"关键因素的不确定性影响","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成多样示意图 import build_interval_sensitivity_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_interval_sensitivity_figure('paper')[0]\nsave_fig(fig, '关键因素的不确定性影响', '样例', mode='paper', sample=True)","source":"def build_interval_sensitivity_figure(mode: str):\n    \"\"\"构造适合灵敏度与稳健性表达的点—区间图。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    data = interval_sensitivity_data()\n    fig, ax = new_fig(width=\"full\", ratio=0.52, mode=mode)\n    recipe = plot_interval_estimates(\n        ax,\n        data[\"labels\"],\n        data[\"estimate\"],\n        data[\"lower\"],\n        data[\"upper\"],\n        interval_label=\"5%–95%蒙特卡洛情景区间\",\n        interval_basis=\"固定 5000 次构造情景的经验分位数\",\n    )\n    ax.set_xlabel(\"目标变化（%）\")\n    ax.set_ylabel(\"扰动因素\")\n    if mode == \"show\":\n        ax.set_title(\"关键因素的不确定性影响\", fontsize=12.0, pad=7.0)\n    fig._cumcm_suggested_caption = (  # type: ignore[attr-defined]\n        \"固定随机种子的合成蒙特卡洛算例展示关键因素对目标值的影响。\"\n        \"圆点为 5000 次构造情景的中位数，水平线为经验 5%–95% 分位范围；\"\n        \"因素按点估计绝对值排序。区间跨越零只说明在该情景设定下方向不稳定，\"\n        \"不能替代统计显著性检验。所有数值均为示例。\"\n    )\n    return fig, ax, recipe","preview":"assets/workflow/local-interval-sensitivity.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_interval_estimates","signature":"plot_interval_estimates(ax, labels: Sequence[str], estimates: Sequence[float] | np.ndarray, lower: Sequence[float] | np.ndarray, upper: Sequence[float] | np.ndarray, *, interval_label: str, interval_basis: str, sort_by_magnitude: bool=True)"}]},{"id":"local-correlation-mantel","chartTypeZh":"相关矩阵与 Mantel 关系网络","builder":"build_correlation_mantel_figure","builderSignature":"build_correlation_mantel_figure(mode: str)","sourceRelativePath":"绘图样式/生成多样示意图.py","inputAdaptation":"提供 correlation/correlation_p/labels，以及来源组、目标变量、Mantel r/p；说明距离矩阵、p 校正及边筛选依据。","scientificBoundary":"相关不等于因果；现生成器内部会计算合成数据的置换检验，正式绘图应直接消费已验证统计结果。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["matrix-correlation-heatmap"],"title":"变量相关结构与距离矩阵关联","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成多样示意图 import build_correlation_mantel_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_correlation_mantel_figure('paper')[0]\nsave_fig(fig, '变量相关结构与距离矩阵关联', '样例', mode='paper', sample=True)","source":"def build_correlation_mantel_figure(mode: str):\n    \"\"\"构造相关三角热力图与 Mantel 关系网络的组合示意图。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    data = correlation_mantel_data()\n    fig, ax = new_fig(width=\"full\", ratio=0.56, mode=mode)\n    recipe = plot_correlation_mantel_network(\n        ax,\n        data[\"correlation\"],\n        data[\"labels\"],\n        data[\"correlation_p\"],\n        data[\"links\"],\n        correlation_p_basis=\"91 个 Pearson 两侧检验的 Holm 校正 p 值\",\n        mantel_p_basis=\"各来源组内 14 次 Mantel 双侧 1999 置换的 BH-FDR 校正 p 值\",\n        source_basis={\n            \"物种组1\": \"物种组 1 的两列标准化丰度特征欧氏距离\",\n            \"物种组2\": \"物种组 2 的两列标准化丰度特征欧氏距离\",\n            \"物种组3\": \"物种组 3 的两列标准化丰度特征欧氏距离\",\n            \"物种组4\": \"物种组 4 的两列标准化丰度特征欧氏距离\",\n        },\n        link_selection_basis=\"展示 4×14 项预注册检验全量；p≥0.05 置于浅灰背景层\",\n        triangle=\"upper\",\n        show_nonsignificant=True,\n    )\n    # 色标固定在右下独立留白；上缘低于 Mantel 效应量图例，避免展示版字号放大后\n    # 两组说明彼此碰撞。\n    colorbar_axis = ax.inset_axes((0.965, 0.035, 0.018, 0.235))\n    colorbar = fig.colorbar(\n        recipe[\"mesh\"],\n        cax=colorbar_axis,\n    )\n    # 配方已把 Pearson r 的色域固定为完整理论定义域 [-1, 1]。TwoSlopeNorm 在\n    # Matplotlib 3.10 中会让 colorbar 使用函数标尺，查询端点 minor ticks 时可能\n    # 计算出无限容差并发出 RuntimeWarning；由于此处关于 0 完全对称，恢复 linear\n    # 不改变颜色映射。切勿在样本自适应色域上这样扩刻度，否则会产生空白色块。\n    colorbar.ax.set_yscale(\"linear\")\n    colorbar.set_ticks((-1.0, -0.5, 0.0, 0.5, 1.0))\n    colorbar.ax.yaxis.set_ticks_position(\"right\")\n    colorbar.ax.tick_params(labelsize=8.0 if mode == \"paper\" else 9.0)\n    colorbar.ax.text(\n        0.5,\n        1.04,\n        \"Pearson\\n相关系数 r\",\n        transform=colorbar.ax.transAxes,\n        ha=\"center\",\n        va=\"bottom\",\n        multialignment=\"center\",\n        linespacing=0.92,\n        fontsize=8.0 if mode == \"paper\" else 9.0,\n    )\n    if mode == \"show\":\n        ax.set_title(\"变量相关结构与距离矩阵关联\", fontsize=12.0, pad=9.0)\n    fig._cumcm_suggested_caption = (  # type: ignore[attr-defined]\n        f\"固定随机种子的生态结构合成算例（n={data['sample_count']}）。上三角颜色表示 \"\n        \"Pearson r，星号表示 91 次两侧检验经 Holm 校正后的显著性；弧线比较\"\n        \"四个已定义物种组距离矩阵与 14 个环境变量距离矩阵，采用双侧 1999 次置换\"\n        \"Mantel 检验并在每个物种组内做 BH-FDR 校正。浅灰细线保留预注册检验全貌，\"\n        \"显著关系提到上层；弧线宽度编码 |Mantel r|，颜色和线型共同编码校正 p 值。\"\n        \"相关与距离关联均不能单独支持因果结论；所有数值均为示例。\"\n    )\n    return fig, ax, recipe","preview":"assets/workflow/local-correlation-mantel.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_correlation_mantel_network","signature":"plot_correlation_mantel_network(ax, correlation: Sequence[Sequence[float]] | np.ndarray, labels: Sequence[str], correlation_p: Sequence[Sequence[float]] | np.ndarray, links: Sequence[tuple[str, str, float, float]], *, correlation_p_basis: str, mantel_p_basis: str, source_basis: Mapping[str, str], link_selection_basis: str, triangle: Literal['upper', 'lower']='upper', show_nonsignificant: bool=True, legend_bbox: tuple[float, float] | None=None)"}]},{"id":"local-flow-network","chartTypeZh":"有向流量网络","builder":"build_flow_network_figure","builderSignature":"build_flow_network_figure(mode: str)","sourceRelativePath":"绘图样式/生成多样示意图.py","inputAdaptation":"将 flow_network_data() 的 nodes 节点位置/角色与 edges 起点/终点/流量改成同源网络；保留面积与线宽数值图例。","scientificBoundary":"当前位置布局和流量为构造样例；没有执行运输优化，不应自动称为最优网络。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["sankey-energy"],"title":"物流网络的流量结构","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成多样示意图 import build_flow_network_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_flow_network_figure('paper')[0]\nsave_fig(fig, '物流网络的流量结构', '样例', mode='paper', sample=True)","source":"def build_flow_network_figure(mode: str):\n    \"\"\"构造节点规模与边宽同时编码的三层物流网络图。\"\"\"\n    if mode not in {\"paper\", \"show\"}:\n        raise ValueError(\"mode 只能是 paper 或 show\")\n    data = flow_network_data()\n    nodes = data[\"nodes\"]\n    edges = data[\"edges\"]\n    assert isinstance(nodes, dict)\n    assert isinstance(edges, tuple)\n    palette = SHOWCASE_SERIES if mode == \"show\" else SERIES\n    fig, ax = new_fig(width=\"full\", ratio=0.58, mode=mode)\n\n    throughput = {name: 0.0 for name in nodes}\n    maximum_flow = max(float(edge[2]) for edge in edges)\n    for source, target, flow in edges:\n        throughput[source] = max(throughput[source], float(flow))\n        throughput[target] = max(throughput[target], float(flow))\n        x0, y0, source_stage = nodes[source]\n        x1, y1, _ = nodes[target]\n        curvature = 0.055 if (int(y0 + y1) // 10) % 2 == 0 else -0.055\n        arrow = FancyArrowPatch(\n            (x0, y0),\n            (x1, y1),\n            arrowstyle=\"-|>\",\n            connectionstyle=f\"arc3,rad={curvature}\",\n            mutation_scale=6.5 if mode == \"paper\" else 7.0,\n            linewidth=0.85 + 3.0 * float(flow) / maximum_flow,\n            color=palette[0] if source_stage == 0 else palette[2],\n            alpha=0.48,\n            shrinkA=21.0,\n            shrinkB=21.0,\n            zorder=ZORDER[\"主线\"],\n        )\n        ax.add_patch(arrow)\n\n    node_artists = []\n    for stage in range(3):\n        stage_nodes = [\n            (name, values)\n            for name, values in nodes.items()\n            if int(values[2]) == stage\n        ]\n        x_values = [float(values[0]) for _, values in stage_nodes]\n        y_values = [float(values[1]) for _, values in stage_nodes]\n        sizes = [\n            (220.0 if mode == \"paper\" else 330.0)\n            + (220.0 if mode == \"paper\" else 310.0)\n            * throughput[name]\n            / maximum_flow\n            for name, _ in stage_nodes\n        ]\n        node_artists.append(\n            ax.scatter(\n                x_values,\n                y_values,\n                s=sizes,\n                facecolor=mcolors.to_rgba(palette[stage], alpha=0.22),\n                edgecolor=palette[stage],\n                linewidth=1.15 if mode == \"paper\" else 1.45,\n                zorder=ZORDER[\"实测\"],\n            )\n        )\n        for name, values in stage_nodes:\n            node_label = ax.text(\n                float(values[0]),\n                float(values[1]),\n                name,\n                ha=\"center\",\n                va=\"center\",\n                color=SEMANTIC[\"高对比文字\"],\n                fontsize=8.0 if mode == \"paper\" else 9.2,\n                zorder=ZORDER[\"标注\"],\n            )\n            # 长节点名（如\"区域 III\"）比圆宽，两端会压到圆的描边上；\n            # 白描边给文字一圈缓冲，压边处不再显得被圆边切过\n            node_label.set_path_effects(\n                (path_effects.withStroke(linewidth=2.4, foreground=SEMANTIC[\"背景\"]),)\n            )\n\n    legend_handles = tuple(\n        Line2D(\n            [],\n            [],\n            linestyle=\"none\",\n            marker=\"o\",\n            markersize=7.0 if mode == \"paper\" else 8.5,\n            markerfacecolor=mcolors.to_rgba(palette[index], alpha=0.22),\n            markeredgecolor=palette[index],\n            markeredgewidth=1.0,\n            label=label,\n        )\n        for index, label in enumerate((\"供给端\", \"中转层\", \"需求端\"))\n    )\n    category_legend = ax.legend(\n        handles=legend_handles,\n        loc=\"upper center\",\n        ncols=3,\n        frameon=False,\n        handletextpad=0.35,\n        columnspacing=0.9,\n    )\n    ax.add_artist(category_legend)\n\n    representative_flow = np.asarray((12.0, 27.0, maximum_flow))\n    representative_node_area = (\n        (220.0 if mode == \"paper\" else 330.0)\n        + (220.0 if mode == \"paper\" else 310.0)\n        * representative_flow\n        / maximum_flow\n    )\n    size_legend = add_size_legend(\n        ax,\n        node_artists,\n        representative_flow,\n        representative_node_area,\n        title=\"节点最大流量（件/日）\",\n        basis=\"节点面积按其最大关联日流量线性映射\",\n        loc=\"upper left\",\n        ncols=3,\n    )\n    ax.add_artist(size_legend)\n\n    edge_widths = 0.85 + 3.0 * representative_flow / maximum_flow\n    edge_handles = tuple(\n        Line2D(\n            [],\n            [],\n            color=SEMANTIC[\"中性标注\"],\n            linewidth=float(width),\n            label=f\"{flow:.0f}\",\n        )\n        for flow, width in zip(representative_flow, edge_widths, strict=True)\n    )\n    ax.legend(\n        handles=edge_handles,\n        title=\"边流量（件/日）\",\n        loc=\"upper right\",\n        ncols=3,\n        frameon=False,\n        labelspacing=0.45,\n        handlelength=2.2,\n        handletextpad=0.55,\n    )\n    node_positions = np.asarray(\n        [(float(values[0]), float(values[1])) for values in nodes.values()]\n    )\n    apply_data_limits(\n        ax,\n        node_positions[:, 0],\n        np.concatenate((node_positions[:, 1], [0.0, 100.0])),\n        x_margin_steps=0.45,\n        min_top_reserve=0.16,\n    )\n    ax.set_xticks((0.0, 1.0, 2.0), (\"供给端\", \"中转层\", \"需求端\"))\n    ax.set_xlabel(\"网络层级\")\n    ax.set_ylabel(\"南北位置（km）\")\n    ax.set_axisbelow(True)\n    if mode == \"show\":\n        ax.set_title(\"物流网络的流量结构\", fontsize=12.0, pad=7.0)\n    fig._cumcm_suggested_caption = (  # type: ignore[attr-defined]\n        \"固定合成算例展示供给端—中转层—需求端三层物流网络。\"\n        \"节点面积按该节点最大关联日流量缩放，连线宽度按运输量缩放，\"\n        \"两段网络分别使用柔蓝和薄荷色以区分运输阶段。\"\n        \"该图用于识别主通道和瓶颈位置，精确流量仍应由结果表提供；\"\n        \"所有节点、位置与流量均为示例。\"\n    )\n    return fig, ax","preview":"assets/workflow/local-flow-network.png","helpers":[{"name":"add_size_legend","signature":"add_size_legend(ax, artist: PathCollection | Sequence[PathCollection], values: Sequence[float] | np.ndarray, areas_pt2: Sequence[float] | np.ndarray, *, title: str, basis: str, value_format: str='.0f', loc: str='upper left', ncols: int=1)"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-multiline","chartTypeZh":"多方案时序折线","builder":"build_multiline_figure","builderSignature":"build_multiline_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"x 一维数组、每行一条的 y_series、行对应 labels；通过 plot_line_series 使用稳定编码。","scientificBoundary":"无序系列通常 1–6 条，必须同量纲；不要按各图局部顺序改变同一方案颜色。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple"],"title":"多方案时序趋势对比","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_multiline_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_multiline_figure()\nsave_fig(fig, '多方案时序趋势对比', '样例', mode='paper', sample=True)","source":"def build_multiline_figure():\n    \"\"\"多方案时序折线：比较同量纲序列的趋势、拐点与交叉。\"\"\"\n    month = np.arange(1.0, 13.0)\n    # 末端值需彼此拉开：三条线终点挨在一起时末端直标会挤成一团，\n    # 而末端可分离本就是直标（相对图例）的适用前提\n    series = np.vstack(\n        (\n            68.0 + 2.9 * month + 4.8 * np.sin(month / 1.8),\n            73.0 + 1.7 * month + 6.0 * np.sin((month + 1.0) / 2.0),\n            64.0 + 4.0 * month + 3.2 * np.cos(month / 1.7),\n        )\n    )\n    fig, ax = new_fig(width=\"full\", ratio=0.50, mode=MODE)\n    plot_line_series(\n        ax,\n        month,\n        series,\n        (\"稳健方案\", \"低成本方案\", \"高收益方案\"),\n        direct_labels=True,\n        include_markers=True,\n        focal_label=\"稳健方案\",\n    )\n    ax.set_xlabel(\"时间（月）\")\n    ax.set_ylabel(\"综合效益（分）\")\n    ax.set_xticks(month)\n    apply_data_limits(ax, month, series.ravel(), top_focus_x=float(month[-1]))\n    _set_caption(\n        fig,\n        \"构造算例比较三个候选方案在 12 个月内的综合效益。深蓝线强调契约预先指定的\"\n        \"稳健方案，其余方案退为灰色上下文，线型、点形和末端直标仍保证各曲线可辨；\"\n        \"曲线用于比较趋势、拐点及交叉位置，所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-multiline.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_line_series","signature":"plot_line_series(ax, x: Sequence[float] | np.ndarray, y_series: Sequence[Sequence[float]] | np.ndarray, labels: Sequence[str], *, direct_labels: bool=True, include_markers: bool=True, ordered_by: Sequence[float] | np.ndarray | None=None, focal_label: str | None=None, linewidth: float | None=None, markersize: float | None=None)"}]},{"id":"local-grouped-bar-error","chartTypeZh":"分组柱状与误差棒","builder":"build_grouped_bar_error_figure","builderSignature":"build_grouped_bar_error_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"替换 regions/scenarios/means/standard_error；矩阵行列与标签对应，明确误差为 SE/SD/CI。","scientificBoundary":"原误差数值为演示设定；没有从真实样本估计，不能将任意误差棒称为 95% CI。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["custom-error-bar"],"title":"分组均值与误差范围","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_grouped_bar_error_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_grouped_bar_error_figure()\nsave_fig(fig, '分组均值与误差范围', '样例', mode='paper', sample=True)","source":"def build_grouped_bar_error_figure():\n    \"\"\"分组柱与误差棒：比较类别均值及其抽样不确定性。\"\"\"\n    regions = (\"东部\", \"中部\", \"西部\", \"北部\")\n    scenarios = (\"基准情景\", \"节能情景\", \"协同情景\")\n    means = np.asarray(\n        (\n            (72.0, 68.0, 61.0, 65.0),\n            (77.0, 73.0, 67.0, 70.0),\n            (82.0, 79.0, 74.0, 76.0),\n        )\n    )\n    standard_error = np.asarray(\n        (\n            (1.8, 2.1, 2.4, 2.0),\n            (1.6, 1.9, 2.2, 1.8),\n            (1.5, 1.7, 2.0, 1.7),\n        )\n    )\n    fig, ax = new_fig(width=\"full\", ratio=0.52, mode=MODE)\n    positions = np.arange(len(regions), dtype=float)\n    width = 0.23\n    encodings = series_encoding_map(scenarios, include_marker=False)\n    hatches = HATCH_TRIO\n    for index, scenario in enumerate(scenarios):\n        offset = (index - 1) * width\n        ax.bar(\n            positions + offset,\n            means[index],\n            width=width,\n            yerr=standard_error[index],\n            capsize=2.0,\n            color=encodings[scenario][\"color\"],\n            alpha=0.82,\n            hatch=hatches[index],\n            edgecolor=SEMANTIC[\"背景\"],\n            linewidth=0.8,\n            error_kw={\n                \"ecolor\": SEMANTIC[\"高对比文字\"],\n                \"elinewidth\": 0.8,\n                \"capthick\": 0.8,\n            },\n            label=scenario,\n            zorder=ZORDER[\"主线\"],\n        )\n    ax.set_xticks(positions, regions)\n    ax.set_xlabel(\"区域\")\n    ax.set_ylabel(\"绩效得分（分）\")\n    ax.legend(loc=\"upper left\", ncols=3, frameon=False)\n    apply_data_limits(\n        ax,\n        positions,\n        np.concatenate(([0.0], (means + standard_error).ravel())),\n    )\n    _set_caption(\n        fig,\n        \"构造算例比较四个区域在三种情景下的平均绩效。柱高为 20 次独立重复的样本均值，\"\n        \"误差棒为均值标准误；颜色与纹理共同编码情景，所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-grouped-bar-error.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-stacked-area","chartTypeZh":"累计构成堆叠面积","builder":"build_stacked_area_figure","builderSignature":"build_stacked_area_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"有序横轴与各组成部分同长序列；确认单位、类别互斥和可加总。","scientificBoundary":"不适用于非可加指标或重复计数；中间层的精确变化不如折线易读。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["area-stack"],"title":"累计资源构成变化","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_stacked_area_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_stacked_area_figure()\nsave_fig(fig, '累计资源构成变化', '样例', mode='paper', sample=True)","source":"def build_stacked_area_figure():\n    \"\"\"堆叠面积：同时表达总量变化与构成变化。\n\n    仅当各部分可加总且量纲一致时才使用该图型（选用条件属绘图者纪律，不进图注）。\n    \"\"\"\n    stages = np.arange(1.0, 9.0)\n    transport = np.asarray((22.0, 26.0, 31.0, 34.0, 38.0, 43.0, 47.0, 50.0))\n    storage = np.asarray((18.0, 19.0, 21.0, 22.0, 24.0, 25.0, 27.0, 29.0))\n    processing = np.asarray((16.0, 18.0, 20.0, 24.0, 27.0, 31.0, 34.0, 38.0))\n    fig, ax = new_fig(width=\"full\", ratio=0.50, mode=MODE)\n    layers = ax.stackplot(\n        stages,\n        transport,\n        storage,\n        processing,\n        colors=SERIES[:3],\n        alpha=0.76,\n        zorder=ZORDER[\"主线\"],\n    )\n    for layer, hatch in zip(layers, HATCH_TRIO, strict=True):\n        layer.set_hatch(hatch)\n        layer.set_edgecolor(SEMANTIC[\"背景\"])\n        layer.set_linewidth(0.8)\n    total = transport + storage + processing\n    total_line, = ax.plot(\n        stages,\n        total,\n        color=SEMANTIC[\"高对比文字\"],\n        linewidth=1.25,\n        marker=None,\n        label=\"资源总量\",\n        zorder=ZORDER[\"标注\"],\n    )\n    ax.set_xlabel(\"规划阶段\")\n    ax.set_ylabel(\"资源投入（单位）\")\n    ax.set_xticks(stages)\n    area_handles = tuple(\n        Patch(\n            facecolor=color,\n            edgecolor=SEMANTIC[\"背景\"],\n            hatch=hatch,\n            label=label,\n        )\n        for color, hatch, label in zip(\n            SERIES[:3], HATCH_TRIO, (\"运输\", \"仓储\", \"加工\"), strict=True\n        )\n    )\n    ax.legend(\n        handles=(*area_handles, total_line),\n        loc=\"upper left\",\n        ncols=4,\n        frameon=False,\n    )\n    # 面积图两端留白按最小步长：留整步会让填充区与轴框间露出大片空白\n    apply_data_limits(ax, stages, np.concatenate(([0.0], total)), x_margin_steps=0.4)\n    _set_caption(\n        fig,\n        \"构造算例展示八个规划阶段的运输、仓储与加工资源投入。堆叠层表达构成，\"\n        \"外缘折线表达总量；所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-stacked-area.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-bubble","chartTypeZh":"成本效益气泡散点","builder":"build_bubble_figure","builderSignature":"build_bubble_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"提供等长 x/y/容量/风险四列；面积变换通过 add_size_legend 给出数值图例，颜色配连续色条。","scientificBoundary":"气泡面积而非直径应表达数值；位置关系不证明因果，当前数据为固定种子构造。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["scatter-simple"],"title":"成本效益气泡关系","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_bubble_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_bubble_figure()\nsave_fig(fig, '成本效益气泡关系', '样例', mode='paper', sample=True)","source":"def build_bubble_figure():\n    \"\"\"气泡散点：用位置、面积和连续色标表达四个变量。\"\"\"\n    rng = np.random.default_rng(20260826)\n    cost = rng.uniform(45.0, 125.0, 72)\n    benefit = 56.0 + 0.42 * cost + rng.normal(0.0, 5.5, cost.size)\n    capacity = rng.uniform(40.0, 180.0, cost.size)\n    risk = np.clip(0.78 - 0.0042 * cost + rng.normal(0.0, 0.06, cost.size), 0.08, 0.82)\n    cmap, norm = continuous_scale(risk, kind=\"sequential\")\n\n    def _capacity_to_area(values):\n        # 面积映射只写一处：数据点与图例样点共用，两处各写公式一旦改动不同步，\n        # 尺寸图例就与数据脱节（图例失真是正确性问题不是样式问题）\n        return 16.0 + 70.0 * (values - capacity.min()) / np.ptp(capacity)\n\n    sizes = _capacity_to_area(capacity)\n    fig, ax = new_fig(width=\"full\", ratio=0.54, mode=MODE)\n    bubbles = ax.scatter(\n        cost,\n        benefit,\n        s=sizes,\n        c=risk,\n        cmap=cmap,\n        norm=norm,\n        alpha=0.72,\n        edgecolor=SEMANTIC[\"背景\"],\n        linewidth=0.4,  # 气泡白边细于常规 marker 边（0.75+）：气泡密集重叠，粗边会糊\n        zorder=ZORDER[\"实测\"],\n    )\n    add_continuous_colorbar(fig, bubbles, ax, label=\"风险概率（0–1）\")\n    representative_capacity = np.asarray((60.0, 110.0, 160.0))\n    representative_areas = _capacity_to_area(representative_capacity)\n    add_size_legend(\n        ax,\n        bubbles,\n        representative_capacity,\n        representative_areas,\n        title=\"处理能力（件/日）\",\n        basis=\"处理能力在本样例观测范围内线性映射到 16–86 pt² 的气泡面积\",\n        loc=\"upper left\",\n    )\n    ax.set_xlabel(\"成本（万元）\")\n    ax.set_ylabel(\"综合效益（分）\")\n    apply_data_limits(ax, cost, benefit)\n    _set_caption(\n        fig,\n        \"构造算例展示 72 个候选方案的成本、综合效益、处理能力与风险。横纵位置分别编码\"\n        \"成本和效益，气泡面积编码处理能力，连续色标编码风险概率；精确数值应回到结果表，\"\n        \"所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-bubble.png","helpers":[{"name":"add_continuous_colorbar","signature":"add_continuous_colorbar(fig, mappable: Any, ax, *, label: str, max_ticks: int=5, fraction: float=0.043, pad: float=0.025, shrink: float=1.0, cax: Any | None=None, orientation: Literal['vertical', 'horizontal'] | None=None)"},{"name":"add_size_legend","signature":"add_size_legend(ax, artist: PathCollection | Sequence[PathCollection], values: Sequence[float] | np.ndarray, areas_pt2: Sequence[float] | np.ndarray, *, title: str, basis: str, value_format: str='.0f', loc: str='upper left', ncols: int=1)"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-distribution-density","chartTypeZh":"直方图与核密度","builder":"build_distribution_density_figure","builderSignature":"build_distribution_density_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"用同单位一维样本替换 values，显式选择分箱与 KDE 带宽。","scientificBoundary":"KDE 是平滑估计，分箱与带宽会影响形态；极少样本或常量样本不适用。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["bar-histogram"],"title":"目标值概率分布","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_distribution_density_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_distribution_density_figure()\nsave_fig(fig, '目标值概率分布', '样例', mode='paper', sample=True)","source":"def build_distribution_density_figure():\n    \"\"\"直方图与核密度：比较频数结构和连续分布形状。\"\"\"\n    rng = np.random.default_rng(20260826)\n    values = np.concatenate(\n        (rng.normal(68.0, 5.0, 180), rng.normal(79.0, 3.2, 120))\n    )\n    grid = np.linspace(float(values.min()), float(values.max()), 320)\n    density = gaussian_kde(values)(grid)\n    # 先算柱高再画：直方图峰值常高于核密度峰值，纵轴上界必须同时覆盖两者，\n    # 只按核密度定界会把最高的几根柱子削平（实测裁顶）\n    hist_heights, hist_edges = np.histogram(values, bins=18, density=True)\n    fig, ax = new_fig(width=\"full\", ratio=0.50, mode=MODE)\n    ax.hist(\n        values,\n        bins=hist_edges,\n        density=True,\n        color=SERIES[0],\n        alpha=0.42,\n        edgecolor=SEMANTIC[\"背景\"],\n        linewidth=0.8,\n        label=\"经验频数\",\n        zorder=ZORDER[\"区间\"],\n    )\n    ax.plot(\n        grid,\n        density,\n        color=SERIES[1],\n        linewidth=1.5,\n        linestyle=\"-\",\n        marker=None,\n        label=\"核密度估计\",\n        zorder=ZORDER[\"主线\"],\n    )\n    ax.set_xlabel(\"收益得分（分）\")\n    ax.set_ylabel(\"概率密度（1/分）\")\n    ax.legend(loc=\"upper left\", frameon=False)\n    apply_data_limits(ax, grid, np.concatenate(([0.0], density, hist_heights)))\n    _set_caption(\n        fig,\n        \"构造算例用直方图保留 300 个收益样本的经验频数结构，并叠加高斯核密度估计以\"\n        \"辅助识别双峰。核密度带宽由数据自动估计，不作为显著性证据；所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-distribution-density.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-contour","chartTypeZh":"二维响应等高线","builder":"build_contour_figure","builderSignature":"build_contour_figure(surface_data=None)","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"可传 surface_data=(allocation, service, X, Y, Z)，两条轴向量与同形二维网格一致；文字单位也需适配。","scientificBoundary":"与三维图共享数据、色域和等高线；网格最优点不等于已证明连续全局最优。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["heatmap-cartesian"],"title":"双因素响应等高线","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_contour_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_contour_figure()\nsave_fig(fig, '双因素响应等高线', '样例', mode='paper', sample=True)","source":"def build_contour_figure(surface_data=None):\n    \"\"\"二维响应等高线：与三维伴随图共用数据，承担精确定位和读数。\"\"\"\n    if surface_data is None:\n        surface_data = _response_surface_sample()\n    allocation, service, x_grid, y_grid, response = surface_data\n    # 同数据伴随图是三维曲面的精确读数层，必须继承 TERRAIN 色带与同一数值域；\n    # 普通、无三维伴随关系的独立等高线图仍可按任务语义选 YlOrRd 等顺序色带。\n    cmap, norm = continuous_scale(response, kind=\"sequential\", palette=TERRAIN)\n    filled_levels = np.linspace(float(response.min()), float(response.max()), 16)\n    fig, ax = new_fig(width=\"full\", ratio=0.58, mode=MODE)\n    filled = ax.contourf(\n        x_grid,\n        y_grid,\n        response,\n        levels=filled_levels,\n        cmap=cmap,\n        norm=norm,\n        alpha=0.92,\n        zorder=ZORDER[\"区间\"],\n    )\n    # 与三维底面投影使用同一 16 级等高线；只标注隔级数值，避免精确层变成文字网。\n    contour_lines = ax.contour(\n        x_grid,\n        y_grid,\n        response,\n        levels=filled_levels,\n        colors=[SEMANTIC[\"背景\"]],\n        linewidths=0.7,\n        alpha=0.78,\n        zorder=ZORDER[\"主线\"],\n    )\n    contour_labels = ax.clabel(\n        contour_lines,\n        levels=filled_levels[1:-3:2],\n        inline=True,\n        fontsize=8.0,\n        fmt=\"%.0f\",\n        colors=SEMANTIC[\"中性标注\"],\n    )\n    for label in contour_labels:\n        label.set_path_effects(\n            [\n                path_effects.Stroke(linewidth=2.2, foreground=SEMANTIC[\"背景\"]),\n                path_effects.Normal(),\n            ]\n        )\n    best = np.unravel_index(int(np.argmax(response)), response.shape)\n    best_marker = ax.scatter(\n        [x_grid[best]],\n        [y_grid[best]],\n        s=32.0,\n        marker=\"o\",\n        color=SEMANTIC[\"最优标注\"],\n        edgecolor=SEMANTIC[\"背景\"],\n        linewidth=0.8,\n        label=\"最优网格点\",\n        zorder=ZORDER[\"标注\"],\n    )\n    best_label = ax.annotate(\n        \"最优点\",\n        xy=(float(x_grid[best]), float(y_grid[best])),\n        xytext=(7, -13),\n        textcoords=\"offset points\",\n        color=SEMANTIC[\"中性标注\"],\n        fontsize=8.0,\n        ha=\"left\",\n        va=\"top\",\n        arrowprops={\n            \"arrowstyle\": \"-\",\n            \"color\": SEMANTIC[\"中性标注\"],\n            \"linewidth\": 0.8,\n            \"shrinkA\": 1.5,\n            \"shrinkB\": 3.5,\n        },\n        zorder=ZORDER[\"标注\"],\n    )\n    best_label.set_path_effects(\n        [\n            path_effects.Stroke(linewidth=2.2, foreground=SEMANTIC[\"背景\"]),\n            path_effects.Normal(),\n        ]\n    )\n    best_marker.set_gid(\"cumcm_response_surface_optimum\")\n    add_continuous_colorbar(fig, filled, ax, label=\"综合效益（分）\")\n    ax.set_xlabel(\"资源投放（万元）\")\n    ax.set_ylabel(\"服务水平（%）\")\n    # 单一最优点直接短标，不再用大框图例占据响应面。\n    # 连续场贴边：填充域=数据域，四周留白会露出「缺一块」似的白带（用户反馈已踩）\n    apply_field_limits(ax, allocation, service)\n    _register_response_surface_pair(\n        fig,\n        allocation=allocation,\n        service=service,\n        response=response,\n        cmap=cmap,\n        norm=norm,\n        levels=filled_levels,\n        role=\"precise_contour2d\",\n    )\n    _set_caption(\n        fig,\n        \"本图与《双因素响应三维曲面》使用完全相同的 X/Y/Z 网格、色标范围、16 级等高线\"\n        \"和最优网格点；填色与标注等高线用于精确判断主效益带、局部峰谷及参数范围，深蓝\"\n        \"圆点为离散网格中的全局最优点。该点不是连续全局最优证明，所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-contour.png","helpers":[{"name":"add_continuous_colorbar","signature":"add_continuous_colorbar(fig, mappable: Any, ax, *, label: str, max_ticks: int=5, fraction: float=0.043, pad: float=0.025, shrink: float=1.0, cax: Any | None=None, orientation: Literal['vertical', 'horizontal'] | None=None)"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-contour-surface","chartTypeZh":"三维响应曲面与底面等高线","builder":"build_contour_surface_figure","builderSignature":"build_contour_surface_figure(surface_data=None)","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"可传与二维图完全相同的 surface_data 五元组；推荐同时调用 build_contour_figure。","scientificBoundary":"三维用于形态感知，精确读数依靠二维伴随图；默认无参数仍生成合成曲面。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["heatmap-cartesian"],"title":"双因素响应三维曲面","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_contour_surface_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_contour_surface_figure()\nsave_fig(fig, '双因素响应三维曲面', '样例', mode='paper', sample=True)","source":"def build_contour_surface_figure(surface_data=None):\n    \"\"\"三维响应曲面（光照晕渲）：曲面悬浮于上、等值线投影分离于下。\n\n    样式参照 MATLAB 科研惯例（meshc/surfl 构图）：LightSource 晕渲增强梯度立体感，\n    投影与曲面拉开距离避免贴底混叠；分工不变——三维承担形态感知，精确读数以并列\n    的二维等高线图为准，不单独用三维下数值结论。\n    \"\"\"\n    if surface_data is None:\n        surface_data = _response_surface_sample()\n    allocation, service, x_grid, y_grid, response = surface_data\n\n    # 参考样式定案（2026-08-26 队长指定）：MATLAB 地形晕渲同款地形色带（统一色板\n    # TERRAIN）；改配色时经 continuous_scale(palette=...) 换 viridis 等即可，渲染链不变\n    cmap, norm = continuous_scale(response, kind=\"sequential\", palette=TERRAIN)\n    z_min = float(np.min(response))\n    z_max = float(np.max(response))\n    跨度 = z_max - z_min\n    底 = z_min - 0.55 * 跨度  # 投影与曲面分离，同时不过度压缩主曲面的垂直空间\n\n    # 制图学三层合成（2026-08-26 定稿，取代单向 LightSource.shade）：\n    # 多方向晕渲 + SVF 环境光遮蔽 + 瑞士式微调，全部烘焙进面色（见 _bake_terrain_rgb）\n    rgb = _bake_terrain_rgb(response, cmap, vert_exag=3.0)\n\n    fig, _ = new_fig(width=\"full\", ratio=0.72, mode=MODE)\n    fig.clf()\n    # 3D Axes 在宽画布中会强制保留物理正方形；若继续交给 constrained_layout，\n    # 主轴会缩到画布右下并留出大块左上空白。单轴 3D 图因此固定可复测的画布矩形，\n    # 色标改放原本闲置的顶部区域，不再与 z 轴标签并排争夺右侧空间。\n    fig.set_layout_engine(\"none\")\n    main_rect = (-0.020, 0.075, 0.820, 0.900)\n    colorbar_rect = (0.680, 0.875, 0.240, 0.024)\n    ax = fig.add_axes(main_rect, projection=\"3d\", computed_zorder=False)\n    colorbar_ax = fig.add_axes(colorbar_rect)\n    ax.computed_zorder = False  # 静态定稿视角下手动层序，消除投影穿过曲面\n    # rstride/cstride=1 全分辨率渲染：默认 rcount=50 会降采样抹掉晕渲细节\n    surface = ax.plot_surface(\n        x_grid, y_grid, response,\n        facecolors=rgb, rstride=1, cstride=1,\n        linewidth=0.0, antialiased=False, shade=False,\n    )\n    surface.set_zorder(4)\n    # 投影必须低于曲面：屏幕投影相交时由曲面正确遮挡，不再为了“完整线条”让\n    # 底部等高线穿过山体。\n    # 3D 等值线在新版 matplotlib 里没有 .collections——用「画前画后差集」精确拿到\n    # 投影线对象再设层序（分离构图须投影完整；曲面与其他元素不受牵连）\n    已有 = set(map(id, ax.collections))\n    contour_levels = np.linspace(z_min, z_max, 16)\n    ax.contour(\n        x_grid, y_grid, response,\n        levels=contour_levels, cmap=cmap, norm=norm,\n        offset=底, linewidths=0.9,\n    )\n    for _coll in ax.collections:\n        if id(_coll) not in 已有:\n            _coll.set_zorder(2)\n    best = np.unravel_index(int(np.argmax(response)), response.shape)\n    bx, by, bz = float(x_grid[best]), float(y_grid[best]), float(response[best])\n    ax.scatter(\n        [bx], [by], [bz + 0.012 * 跨度],\n        s=28.0, marker=\"o\", alpha=0.92,\n        color=SEMANTIC[\"最优标注\"], edgecolor=SEMANTIC[\"背景\"],\n        linewidth=0.8, depthshade=False, zorder=7,\n    )\n    x_step = 20.0\n    y_step = 10.0\n    x_ticks = np.arange(\n        np.ceil(float(allocation.min()) / x_step) * x_step,\n        np.floor(float(allocation.max()) / x_step) * x_step + 0.5 * x_step,\n        x_step,\n    )\n    y_ticks = np.arange(\n        np.ceil(float(service.min()) / y_step) * y_step,\n        np.floor(float(service.max()) / y_step) * y_step + 0.5 * y_step,\n        y_step,\n    )\n    apply_collection3d_limits(\n        ax,\n        allocation,\n        service,\n        np.concatenate((np.asarray((底,)), response.ravel())),\n        z_top_pad=0.06 * 跨度,\n        y_ticks=y_ticks,\n    )\n    ax.set_xticks(x_ticks)\n    ax.zaxis.set_major_locator(MaxNLocator(nbins=5, min_n_ticks=4))\n    ax.set_xlabel(\"资源投放（万元）\", labelpad=7)\n    ax.set_ylabel(\"服务水平（%）\", labelpad=7)\n    ax.set_zlabel(\"综合效益（分）\", labelpad=4)\n    ax.tick_params(axis=\"x\", pad=1.5)\n    ax.tick_params(axis=\"y\", pad=1.5)\n    ax.tick_params(axis=\"z\", pad=2.0)\n\n    # 正交投影消除近大远小，抬高视点将曲面与底部投影拉开；zoom>1 只放大主体，\n    # 不篡改数据范围。短横色标复用顶部留白，避免与 z 轴量名重复挤压。\n    colorbar = _finish_3d_axes(\n        fig, ax, elev=34, azim=-54, box_aspect=(1.20, 1.0, 0.72), zoom=1.16,\n        cmap=cmap, norm=norm, values=response, colorbar_label=\"综合效益（分）\",\n        projection=\"ortho\", colorbar_axis=colorbar_ax,\n        colorbar_orientation=\"horizontal\", transparent_panes=True,\n    )\n    colorbar.ax.xaxis.set_label_position(\"top\")\n    _add_3d_floor_frame(\n        ax,\n        (float(allocation.min()), float(allocation.max())),\n        (float(service.min()), float(service.max())),\n        底,\n    )\n    ax._cumcm_surface_layout = {\n        \"projection\": \"orthographic\",\n        \"camera\": (34.0, -54.0, 0.0),\n        \"main_rect\": main_rect,\n        \"colorbar_rect\": colorbar_rect,\n        \"contour_levels\": len(contour_levels),\n        \"bottom_offset_ratio\": 0.55,\n        \"layer_zorders\": {\"floor_frame\": 1, \"contour\": 2, \"surface\": 4},\n    }\n    _register_response_surface_pair(\n        fig,\n        allocation=allocation,\n        service=service,\n        response=response,\n        cmap=cmap,\n        norm=norm,\n        levels=contour_levels,\n        role=\"shape_surface3d\",\n    )\n    _set_caption(\n        fig,\n        \"多峰响应面呈现资源投放与服务水平共同作用下的主效益带、局部次峰和低效区；\"\n        \"下方 16 级等高线辅助判断主脊走向，曲面深蓝圆点表示全局最优网格点。三维图\"\n        \"只承担形态感知，最优点的精确平面定位与读数以并列的二维等高线图为准；\"\n        \"所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-contour-surface.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-ridgeline","chartTypeZh":"阶段分布山脊图","builder":"build_ridgeline_figure","builderSignature":"build_ridgeline_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"提供按期排序的分组样本与共同横轴，以 gaussian_kde 估计各组密度，统一带宽和尺度。","scientificBoundary":"错叠高度不是额外指标；密度平滑和每组归一化方式必须说明。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["bar-histogram"],"title":"分布形态阶段演化山脊","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_ridgeline_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_ridgeline_figure()\nsave_fig(fig, '分布形态阶段演化山脊', '样例', mode='paper', sample=True)","source":"def build_ridgeline_figure():\n    \"\"\"山脊图：多组分布沿类别/时间错叠，读分布形态的演化（MATLAB 图集学习成果）。\"\"\"\n    rng = np.random.default_rng(20260826)\n    stage_labels = (\"第一期\", \"第二期\", \"第三期\", \"第四期\", \"第五期\", \"第六期\")\n    stage_count = len(stage_labels)\n    grid = np.linspace(30.0, 110.0, 400)\n    densities = []\n    for index in range(stage_count):\n        center = 52.0 + 6.5 * index\n        spread = 11.0 - 0.9 * index\n        sample = np.concatenate((\n            rng.normal(center, spread, 260),\n            rng.normal(center + 14.0, 5.0, 70 + 18 * index),\n        ))\n        densities.append(gaussian_kde(sample)(grid))\n    densities = np.asarray(densities)\n    峰高 = float(densities.max())\n    间距 = 0.72 * 峰高  # 轻微重叠是山脊图的特征，读的是形态迁移\n    cmap, norm = continuous_scale(\n        np.arange(stage_count, dtype=float), kind=\"sequential\"\n    )\n    fig, ax = new_fig(width=\"full\", ratio=0.62, mode=MODE)\n    for index in range(stage_count - 1, -1, -1):\n        baseline = index * 间距\n        curve = baseline + densities[index]\n        color = cmap(norm(float(index)))\n        ax.fill_between(\n            grid, baseline, curve,\n            facecolor=color, alpha=0.85, zorder=ZORDER[\"主线\"] + (stage_count - index),\n        )\n        ax.plot(\n            grid, curve,\n            color=SEMANTIC[\"背景\"], linewidth=1.1,\n            zorder=ZORDER[\"主线\"] + (stage_count - index),\n        )\n    ax.set_xlabel(\"综合效益（分）\")\n    ax.set_ylabel(\"推进阶段\")\n    # 山脊图 y 轴是\"行基线\"类别语义，走 categorical_y 统一入口登记；\n    # 入口按基线位置定的上界会裁掉顶行波峰，再按数据（顶行峰高）扩顶界\n    baselines = [index * 间距 for index in range(stage_count)]\n    apply_categorical_y_limits(\n        ax, grid, stage_labels, positions=baselines, x_margin_steps=0.5\n    )\n    extend_categorical_y_top(ax, float((stage_count - 1) * 间距 + 1.06 * 峰高))\n    _set_caption(\n        fig,\n        \"构造算例展示六个推进阶段的综合效益分布演化：每行是该阶段效益的核密度曲线，\"\n        \"行间轻微重叠便于对齐比较。分布主峰逐期右移、集中度提高，右侧次峰占比渐增；\"\n        \"行序颜色由统一连续色带映射，所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-ridgeline.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-diverging-area","chartTypeZh":"相对基线的正负面积","builder":"build_diverging_area_figure","builderSignature":"build_diverging_area_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"有序横轴与相对明确基线的偏差值；保留零线及正负填充语义。","scientificBoundary":"只有同单位的偏差能比较；不能用不明基线制造正负结论。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["area-stack"],"title":"库存盈缺正负面积","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_diverging_area_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_diverging_area_figure()\nsave_fig(fig, '库存盈缺正负面积', '样例', mode='paper', sample=True)","source":"def build_diverging_area_figure():\n    \"\"\"正负面积图：一条序列相对基线的上下偏差双色填充（MATLAB 图集学习成果）。\"\"\"\n    week = np.arange(1.0, 25.0)\n    deviation = (\n        6.5 * np.sin(week / 2.6)\n        + 3.0 * np.cos(week / 1.4)\n        + np.linspace(-1.5, 4.0, week.size)\n    )\n    fig, ax = new_fig(width=\"full\", ratio=0.48, mode=MODE)\n    # 安全线是被读数的主体参照（正负分界即结论），故用炭黑实线；\n    # 全库其余\"背景参照\"零线均为分期灰虚线，两者语义不同\n    ax.axhline(0.0, color=SEMANTIC[\"高对比文字\"], linewidth=1.0, zorder=ZORDER[\"分期\"])\n    # 正负两色转灰度后明度几乎相同（实测：黑白打印时两个填充区糊成同一种灰、\n    # 图例两个色块无从分辨），故加纹理作冗余编码——颜色失效时靠纹理仍可区分\n    ax.fill_between(\n        week, deviation, 0.0, where=deviation >= 0.0, interpolate=True,\n        facecolor=SEMANTIC[\"主推模型\"], alpha=0.75,\n        hatch=HATCH_TRIO[0], edgecolor=SEMANTIC[\"背景\"], linewidth=0.0,\n        zorder=ZORDER[\"主线\"],\n    )\n    ax.fill_between(\n        week, deviation, 0.0, where=deviation < 0.0, interpolate=True,\n        facecolor=SEMANTIC[\"警戒超标\"], alpha=0.75,\n        hatch=HATCH_TRIO[1], edgecolor=SEMANTIC[\"背景\"], linewidth=0.0,\n        zorder=ZORDER[\"主线\"],\n    )\n    ax.plot(\n        week, deviation,\n        color=SEMANTIC[\"高对比文字\"], linewidth=1.2, zorder=ZORDER[\"标注\"],\n    )\n    ax.legend(\n        handles=(\n            Patch(\n                facecolor=SEMANTIC[\"主推模型\"], alpha=0.75, hatch=HATCH_TRIO[0],\n                edgecolor=SEMANTIC[\"背景\"], label=\"高于安全线（盈余）\",\n            ),\n            Patch(\n                facecolor=SEMANTIC[\"警戒超标\"], alpha=0.75, hatch=HATCH_TRIO[1],\n                edgecolor=SEMANTIC[\"背景\"], label=\"低于安全线（缺口）\",\n            ),\n        ),\n        loc=\"upper left\", frameon=False,\n    )\n    ax.set_xlabel(\"周次\")\n    ax.set_ylabel(\"库存偏差（吨）\")\n    ax.set_xticks(week[::2])\n    apply_data_limits(ax, week, np.concatenate(([0.0], deviation)))\n    _set_caption(\n        fig,\n        \"构造算例展示 24 周库存相对安全线的偏差：基线以上为盈余、以下为缺口，\"\n        \"双色填充让正负区段与转换时点一眼可辨；面积大小对应累计偏差量，\"\n        \"所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-diverging-area.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-gradient-line","chartTypeZh":"连续强度渐变折线","builder":"build_gradient_line_figure","builderSignature":"build_gradient_line_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"提供单条 x/y 序列与线段对应连续色值；设置一致色域和色条。","scientificBoundary":"本例颜色重复编码 y 强度，不是另一独立变量；不适合多系列分类颜色。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple"],"title":"负荷强度渐变折线","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_gradient_line_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_gradient_line_figure()\nsave_fig(fig, '负荷强度渐变折线', '样例', mode='paper', sample=True)","source":"def build_gradient_line_figure():\n    \"\"\"渐变折线：线段颜色随取值映射连续色带（MATLAB 图集学习成果）。\n\n    颜色编码的是纵轴数值本身（同一变量的强度），与\"一色一系列\"的分类用色不冲突；\n    必须配色条说明映射，且只用于单序列。\n    \"\"\"\n    hour = np.linspace(0.0, 72.0, 300)\n    load = (\n        58.0\n        + 16.0 * np.sin((hour - 8.0) * np.pi / 12.0) * (0.75 + 0.25 * np.cos(hour / 36.0))\n        + 5.5 * np.sin(hour / 3.4)\n        + np.linspace(0.0, 6.0, hour.size)\n    )\n    cmap, norm = continuous_scale(load, kind=\"sequential\")\n    points = np.stack((hour, load), axis=1).reshape(-1, 1, 2)\n    segments = np.concatenate((points[:-1], points[1:]), axis=1)\n    fig, ax = new_fig(width=\"full\", ratio=0.48, mode=MODE)\n    gradient_line = LineCollection(\n        segments, cmap=cmap, norm=norm,\n        linewidths=2.4, capstyle=\"round\", zorder=ZORDER[\"主线\"],  # 宽于常规主线：线身要承载色带渐变\n    )\n    gradient_line.set_array(0.5 * (load[:-1] + load[1:]))\n    ax.add_collection(gradient_line)\n    add_continuous_colorbar(fig, gradient_line, ax, label=\"瞬时负荷（兆瓦）\")\n    ax.set_xlabel(\"时间（小时）\")\n    ax.set_ylabel(\"瞬时负荷（兆瓦）\")\n    ax.set_xticks(np.arange(0.0, 73.0, 12.0))\n    apply_data_limits(ax, hour, load)\n    _set_caption(\n        fig,\n        \"构造算例展示 72 小时电力负荷曲线：线段颜色随负荷值沿统一连续色带渐变，\"\n        \"高载时段（亮色）与低谷（暗色）不读坐标也能定位；颜色与纵轴同义，\"\n        \"由右侧色条标定，所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-gradient-line.png","helpers":[{"name":"add_continuous_colorbar","signature":"add_continuous_colorbar(fig, mappable: Any, ax, *, label: str, max_ticks: int=5, fraction: float=0.043, pad: float=0.025, shrink: float=1.0, cax: Any | None=None, orientation: Literal['vertical', 'horizontal'] | None=None)"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-waterfall3d","chartTypeZh":"分布演化三维瀑布","builder":"build_waterfall3d_figure","builderSignature":"build_waterfall3d_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"横轴网格、组别/代次与每组曲线矩阵；明确归一化方式和深度排序。","scientificBoundary":"三维遮挡限制精确比较，配同数据二维山脊/折线；不能把演示代次当算法收敛证据。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple"],"title":"迭代分布三维瀑布","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_waterfall3d_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_waterfall3d_figure()\nsave_fig(fig, '迭代分布三维瀑布', '样例', mode='paper', sample=True)","source":"def build_waterfall3d_figure():\n    \"\"\"三维瀑布图（3D Waterfall）：多组谱线沿深度错位展开（MATLAB 图集学习成果）。\n\n    对应 Origin 模板体系的 3D Waterfall：每代一条填充谱线，读分布形态随代次的\n    演化趋势。三维只承担形态感知，逐代精确比较以并列的二维图（如山脊图）为准。\n    \"\"\"\n    rng = np.random.default_rng(20260826)\n    fitness = np.linspace(40.0, 100.0, 220)\n    generations = np.arange(1.0, 9.0)\n    curves = []\n    for index in range(generations.size):\n        center = 58.0 + 4.2 * index\n        spread = 9.5 - 0.55 * index\n        curve = np.exp(-0.5 * ((fitness - center) / spread) ** 2)\n        curve += 0.28 * np.exp(-0.5 * ((fitness - center - 12.0) / 4.2) ** 2)\n        curve = curve / curve.max() * (0.85 + 0.05 * rng.standard_normal())\n        curves.append(curve)\n    curves = np.asarray(curves)\n    cmap, norm = continuous_scale(generations, kind=\"sequential\")\n\n    # 3D 轴和独立色条在 Matplotlib 3.11 的约束布局中需要更多纵向空间；\n    # 0.52 会把主轴压到零尺寸。该版本的约束布局还会把 3D 投影边界误算为\n    # 巨大负边距，因此本图改用明确、可复现的轴域。\n    fig, _ = new_fig(\n        width=\"full\",\n        ratio=0.62,\n        mode=MODE,\n        preserve_canvas=True,\n        layout=\"none\",\n    )\n    fig.clf()\n    # clf() 会按 mplstyle 的默认值重新启用 constrained layout；3D 瀑布的旧\n    # GridSpec 已被清空，继续约束布局会在 Matplotlib 3.11 除以零。\n    fig.set_layout_engine(\"none\")\n    fig.subplots_adjust(left=0.03, right=0.88, bottom=0.10, top=0.97)\n    ax = fig.add_subplot(111, projection=\"3d\")\n    polygons = []\n    for index in range(generations.size):\n        curve = curves[index]\n        polygon = np.zeros((fitness.size + 2, 2))\n        polygon[1:-1, 0] = fitness\n        polygon[1:-1, 1] = curve\n        polygon[0] = (fitness[0], 0.0)\n        polygon[-1] = (fitness[-1], 0.0)\n        polygons.append(polygon)\n    collection = PolyCollection(\n        polygons,\n        facecolors=[cmap(norm(value)) for value in generations],\n        edgecolors=SEMANTIC[\"高对比文字\"],\n        linewidths=0.9, alpha=0.82,\n    )\n    ax.add_collection3d(collection, zs=generations, zdir=\"y\")\n    apply_collection3d_limits(\n        ax, fitness, generations, np.array((0.0, 1.0)),\n        y_pad=0.5, z_top_pad=0.05, y_ticks=generations,\n    )\n    ax.set_xlabel(\"适应度（分）\", labelpad=8)\n    ax.set_ylabel(\"迭代代次\", labelpad=8)\n    ax.set_zticks((0.0, 0.5, 1.0))\n    _finish_3d_axes(\n        fig, ax, elev=22, azim=-56, box_aspect=(1.4, 0.9, 0.5), zoom=0.96,\n        cmap=cmap, norm=norm, values=generations, colorbar_label=\"迭代代次\",\n    )\n    _set_caption(\n        fig,\n        \"构造算例展示启发式算法八个迭代代次的适应度分布演化：每代一条归一化密度\"\n        \"谱线沿深度方向错位排开，主峰逐代右移、峰形收窄表明种群向高适应度收敛；\"\n        \"代次颜色由统一连续色带映射。三维瀑布承担形态感知，逐代精确比较以并列的\"\n        \"二维图为准；所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-waterfall3d.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-radar","chartTypeZh":"多方案雷达画像","builder":"build_radar_figure","builderSignature":"build_radar_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"5–8 个已同向归一化至 [0,1] 的指标、最多 3 个方案；补同数据数值表。","scientificBoundary":"需证明归一化可比；雷达面积与指标顺序相关，不能据面积断言综合最优。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["radar"],"title":"方案多指标雷达比较","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_radar_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_radar_figure()\nsave_fig(fig, '方案多指标雷达比较', '样例', mode='paper', sample=True)","source":"def build_radar_figure():\n    \"\"\"雷达图：比较少量已同向归一化指标的方案轮廓。\"\"\"\n    indicators = (\"经济性\", \"可靠性\", \"公平性\", \"低碳性\", \"响应性\", \"可实施性\")\n    labels = (\"方案甲\", \"方案乙\", \"方案丙\")\n    values = np.asarray(\n        (\n            (0.82, 0.74, 0.67, 0.78, 0.71, 0.86),\n            (0.70, 0.88, 0.76, 0.69, 0.82, 0.73),\n            (0.76, 0.79, 0.84, 0.86, 0.68, 0.77),\n        )\n    )\n    angles = np.linspace(0.0, 2.0 * np.pi, len(indicators), endpoint=False)\n    closed_angles = np.concatenate((angles, angles[:1]))\n    # 极坐标外圈标签会扩大紧边界；略增画布高度，使导出后的雷达图仍满足登记比例。\n    fig, ax = new_polar_fig(width=\"full\", ratio=0.92, mode=MODE)\n    fig._cumcm_preserve_canvas = True\n    encodings = series_encoding_map(labels, include_marker=True)\n    radar_lines = []\n    for label, row in zip(labels, values, strict=True):\n        closed = np.concatenate((row, row[:1]))\n        encoding = encodings[label]\n        line, = ax.plot(\n            closed_angles,\n            closed,\n            color=encoding[\"color\"],\n            linestyle=encoding[\"linestyle\"],\n            marker=encoding[\"marker\"],\n            linewidth=1.25,\n            markersize=3.2,\n            label=label,\n            zorder=ZORDER[\"主线\"],\n        )\n        radar_lines.append(line)\n        ax.fill(\n            closed_angles,\n            closed,\n            color=encoding[\"color\"],\n            alpha=0.07,  # 三方案填充叠加，极淡才不遮线；轮廓辨识靠线型与点形\n            zorder=ZORDER[\"区间\"],\n        )\n    ax.set_xticks(angles, indicators)\n    apply_polar_limits(ax, radial_min=0.0, radial_max=1.0)\n    set_polar_ticks(\n        ax,\n        (0.25, 0.50, 0.75, 1.00),\n        (\"0.25\", \"0.50\", \"0.75\", \"1.00\"),\n    )\n    # 半径刻度标签必然与某个方向的数据线相交：挪到两条指标轴的中线，\n    # 再加白色描边保证压线时仍可读（雷达图读数依赖这组标签）\n    ax.set_rlabel_position(float(np.rad2deg(angles[0] + np.pi / 6.0)))\n    for radial_label in ax.get_yticklabels():\n        radial_label.set_path_effects(\n            (path_effects.withStroke(linewidth=2.6, foreground=SEMANTIC[\"背景\"]),)\n        )\n    ax.tick_params(axis=\"x\", pad=6.0)\n    # 在固定画布内部预留图例带，避免紧裁剪改变成品比例。\n    fig.subplots_adjust(left=0.07, right=0.93, top=0.95, bottom=0.17)\n    fig.legend(\n        handles=tuple(radar_lines),\n        loc=\"lower center\",\n        bbox_to_anchor=(0.5, 0.015),\n        ncols=3,\n        frameon=False,\n    )\n    _set_caption(\n        fig,\n        \"构造算例比较三个方案在六个已同向归一化指标上的轮廓。距离圆心越远仅表示该指标\"\n        \"归一化得分更高，折线交叉用于识别权衡；雷达图不替代权重与综合评分表，所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-radar.png","helpers":[{"name":"new_polar_fig","signature":"new_polar_fig(width: Literal['full', 'half']='full', ratio: float=0.72, mode: Mode='paper', font_mode: FontMode='song')"}]},{"id":"local-dendrogram","chartTypeZh":"层次聚类树","builder":"build_dendrogram_figure","builderSignature":"build_dendrogram_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"用已明确标准化规则的样本特征矩阵，选择 linkage 方法和距离；或改为接收已验证 linkage 矩阵。","scientificBoundary":"现例直接用合成样本运行 Ward/Euclidean；聚类结构依赖尺度和方法，不是分类准确率。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["tree-basic"],"title":"样本层次聚类树","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_dendrogram_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_dendrogram_figure()\nsave_fig(fig, '样本层次聚类树', '样例', mode='paper', sample=True)","source":"def build_dendrogram_figure():\n    \"\"\"层次聚类树：展示样本合并顺序与聚类距离。\"\"\"\n    rng = np.random.default_rng(20260826)\n    samples = np.vstack(\n        (\n            rng.normal((0.0, 0.0, 0.2), 0.32, size=(4, 3)),\n            rng.normal((2.2, 1.7, 2.0), 0.34, size=(4, 3)),\n            rng.normal((-1.8, 2.0, -1.2), 0.30, size=(4, 3)),\n        )\n    )\n    tree = linkage(samples, method=\"ward\", metric=\"euclidean\")\n    fig, ax = new_fig(width=\"full\", ratio=0.50, mode=MODE)\n    dendrogram(\n        tree,\n        ax=ax,\n        no_labels=True,\n        color_threshold=0.0,\n        above_threshold_color=SERIES[0],\n    )\n    positions = 5.0 + 10.0 * np.arange(samples.shape[0])\n    ax.set_xticks(positions, tuple(f\"样本{i}\" for i in range(1, 13)), rotation=30.0)\n    ax.set_xlabel(\"样本\")\n    ax.set_ylabel(\"Ward 聚类距离（标准化单位）\")\n    apply_data_limits(\n        ax,\n        positions,\n        np.concatenate(([0.0], tree[:, 2])),\n        x_margin_steps=0.40,\n    )\n    _set_caption(\n        fig,\n        \"构造算例对 12 个三维标准化样本做 Ward 层次聚类。分支高度表示簇合并时的欧氏\"\n        \"距离增量，树结构用于选择候选簇数；本图未给定截断阈值、不宣称最终类别数，\"\n        \"所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-dendrogram.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-classification-diagnostic","chartTypeZh":"混淆矩阵与 ROC 诊断","builder":"build_classification_diagnostic_figure","builderSignature":"build_classification_diagnostic_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"接收同一验证集的已计算混淆矩阵、阈值序列及 FPR/TPR；保持正类定义。","scientificBoundary":"当前 ROC 是构造函数曲线，不是任何已训练模型的真实性能；不平衡数据宜再比较 PR。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["matrix-confusion","line-simple"],"title":"分类模型判别性能","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_classification_diagnostic_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_classification_diagnostic_figure()\nsave_fig(fig, '分类模型判别性能', '样例', mode='paper', sample=True)","source":"def build_classification_diagnostic_figure():\n    \"\"\"分类诊断组图：混淆矩阵与 ROC 曲线互补。\"\"\"\n    fig, axes = new_grid(1, 2, width=\"full\", mode=MODE, hero=1)\n    confusion_ax, roc_ax = axes[0]\n    confusion = np.asarray(((86.0, 14.0), (11.0, 89.0)))\n    mesh, _ = plot_annotated_heatmap(\n        confusion_ax,\n        confusion,\n        (\"预测负类\", \"预测正类\"),\n        (\"实际负类\", \"实际正类\"),\n        kind=\"sequential\",\n        value_format=\".0f\",\n    )\n    confusion_ax.set_xlabel(\"预测类别\")\n    confusion_ax.set_ylabel(\"实际类别\")\n    add_continuous_colorbar(\n        fig,\n        mesh,\n        confusion_ax,\n        label=\"样本数（个）\",\n        fraction=0.052,\n        pad=0.028,\n    )\n\n    false_positive = np.linspace(0.0, 100.0, 90)\n    normalized = false_positive / 100.0\n    true_positive = np.vstack(\n        (\n            100.0 * (1.0 - (1.0 - normalized) ** 3.2),\n            100.0 * (1.0 - (1.0 - normalized) ** 2.35),\n            100.0 * (1.0 - (1.0 - normalized) ** 1.75),\n        )\n    )\n    roc_lines = plot_line_series(\n        roc_ax,\n        false_positive,\n        true_positive,\n        (\"模型甲（AUC=0.86）\", \"模型乙（AUC=0.81）\", \"模型丙（AUC=0.74）\"),\n        direct_labels=False,\n        include_markers=False,\n    )\n    # 随机基准进图例：ROC 的对角线是判读三条曲线的参照物，不能只在图注里交代\n    baseline_line, = roc_ax.plot(\n        false_positive,\n        false_positive,\n        color=SEMANTIC[\"分期线\"],\n        linewidth=0.8,\n        linestyle=(0, (3.2, 2.4)),\n        marker=None,\n        label=\"随机基准\",\n        zorder=ZORDER[\"分期\"],\n    )\n    roc_ax.set_xlabel(\"假阳性率（%）\")\n    roc_ax.set_ylabel(\"真阳性率（%）\")\n    roc_ax.legend(\n        handles=(*roc_lines, baseline_line),\n        loc=\"lower right\",\n        title=\"判别模型\",\n        frameon=False,\n    )\n    apply_data_limits(\n        roc_ax,\n        false_positive,\n        np.concatenate((true_positive.ravel(), false_positive)),\n        top_focus_x=100.0,\n    )\n    _set_caption(\n        fig,\n        \"构造分类算例中，(a) 混淆矩阵给出固定阈值下 200 个样本的分类去向；(b) ROC\"\n        \"曲线比较三个模型跨阈值的判别能力，虚线为随机基准。AUC 数值为示例且不代替外部验证。\",\n    )\n    return fig","preview":"assets/workflow/local-classification-diagnostic.png","helpers":[{"name":"add_continuous_colorbar","signature":"add_continuous_colorbar(fig, mappable: Any, ax, *, label: str, max_ticks: int=5, fraction: float=0.043, pad: float=0.025, shrink: float=1.0, cax: Any | None=None, orientation: Literal['vertical', 'horizontal'] | None=None)"},{"name":"new_grid","signature":"new_grid(nrows: int, ncols: int, width: Literal['full', 'half']='full', mode: Mode='paper', share: ShareMode=None, hero: int | tuple[int, int] | None=None, ratio: float | None=None)"},{"name":"plot_annotated_heatmap","signature":"plot_annotated_heatmap(ax, values: Sequence[Sequence[float]] | np.ndarray, x_labels: Sequence[str], y_labels: Sequence[str], *, kind: ContinuousKind, center: float=0.0, value_format: str='+.2f', x_rotation: float=0.0, origin: Literal['upper', 'lower']='upper', annotate: bool=True, fontsize: float | None=None, square_cells: bool=False, domain: Sequence[float] | None=None, domain_basis: str='')"},{"name":"plot_line_series","signature":"plot_line_series(ax, x: Sequence[float] | np.ndarray, y_series: Sequence[Sequence[float]] | np.ndarray, labels: Sequence[str], *, direct_labels: bool=True, include_markers: bool=True, ordered_by: Sequence[float] | np.ndarray | None=None, focal_label: str | None=None, linewidth: float | None=None, markersize: float | None=None)"}]},{"id":"local-gantt","chartTypeZh":"工作包甘特计划图","builder":"build_gantt_figure","builderSignature":"build_gantt_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"替换 tasks/starts/durations/owners/milestones；所有时间同单位，任务持续时间非负。","scientificBoundary":"原文件标题含关键路径，但 builder 只绘起止与里程碑，没有计算关键路径或进度完成率。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":[],"title":"项目任务进度计划","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_gantt_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_gantt_figure()\nsave_fig(fig, '项目任务进度计划', '样例', mode='paper', sample=True)","source":"def build_gantt_figure():\n    \"\"\"甘特图：表达工作包起止、并行关系与里程碑。\"\"\"\n    tasks = (\"数据审计\", \"模型建立\", \"参数标定\", \"稳健性检验\", \"论文整合\", \"终检打包\")\n    starts = np.asarray((0.0, 7.0, 18.0, 31.0, 43.0, 62.0))\n    durations = np.asarray((9.0, 17.0, 15.0, 16.0, 23.0, 10.0))\n    owners = (\"数据\", \"建模\", \"建模\", \"验证\", \"论文\", \"交付\")\n    owner_order = tuple(dict.fromkeys(owners))\n    encodings = series_encoding_map(owner_order, include_marker=False)\n    positions = np.arange(len(tasks), dtype=float)\n    fig, ax = new_fig(width=\"full\", ratio=0.54, mode=MODE)\n    for position, start, duration, owner in zip(\n        positions, starts, durations, owners, strict=True\n    ):\n        ax.barh(\n            position,\n            duration,\n            left=start,\n            height=0.58,\n            color=encodings[owner][\"color\"],\n            edgecolor=SEMANTIC[\"背景\"],\n            linewidth=0.8,\n            zorder=ZORDER[\"主线\"],\n        )\n    # 里程碑必须自带名称：只画虚线而不标注，读者无从知道这三条线是什么节点\n    milestones = ((36.0, \"数据冻结\"), (62.0, \"模型冻结\"), (66.0, \"停止改稿\"))\n    for milestone, milestone_name in milestones:\n        ax.axvline(\n            milestone,\n            color=SEMANTIC[\"分期线\"],\n            linewidth=0.8,\n            linestyle=(0, (3.2, 2.4)),\n            zorder=ZORDER[\"分期\"],\n        )\n        ax.text(\n            milestone, 0.985, f\"{milestone_name} {milestone:.0f} h\",\n            transform=ax.get_xaxis_transform(),\n            rotation=90.0, va=\"top\", ha=\"right\",\n            fontsize=8.0, color=SEMANTIC[\"次要文字\"],\n            zorder=ZORDER[\"标注\"],\n        )\n    ax.set_xlabel(\"竞赛时间（小时）\")\n    ax.set_ylabel(\"工作包\")\n    legend_handles = tuple(\n        Patch(\n            facecolor=encodings[owner][\"color\"],\n            edgecolor=SEMANTIC[\"背景\"],\n            label=owner,\n        )\n        for owner in owner_order\n    )\n    # 左下角是最后两项任务开工前的空白时段：图例放这里既不压条带，\n    # 也让出右上角给里程碑竖排标签\n    ax.legend(handles=legend_handles, loc=\"lower left\", ncols=3, frameon=False)\n    limit_metadata = apply_categorical_y_limits(\n        ax,\n        np.concatenate((starts, starts + durations, (0.0, 74.0))),\n        tasks,\n        positions=positions,\n        x_margin_steps=0.40,\n    )\n    ax.invert_yaxis()\n    limit_metadata.update(\n        {\n            \"layout_kind\": \"categorical_y\",\n            \"x_expected\": tuple(map(float, ax.get_xlim())),\n            \"y_expected\": tuple(map(float, ax.get_ylim())),\n        }\n    )\n    _set_caption(\n        fig,\n        \"构造的 74 小时竞赛计划展示六个工作包的起止时间和并行关系；竖虚线为 36、62、\"\n        \"66 小时里程碑。条形位置表达计划而非真实完成度，所有时间均为流程示例。\",\n    )\n    return fig","preview":"assets/workflow/local-gantt.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]},{"id":"local-heatmap","chartTypeZh":"带数值标注的指标热图","builder":"build_heatmap_figure","builderSignature":"build_heatmap_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"有限二维矩阵、行列标签和真实比较基准；调用 plot_annotated_heatmap，颜色语义顺序/发散二选一。","scientificBoundary":"样例 0.78 是预设演示基准；没有真实中点时不要机械采用发散色标。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["heatmap-cartesian","matrix-correlation-heatmap"],"title":"方案指标得分热图","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_heatmap_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_heatmap_figure()\nsave_fig(fig, '方案指标得分热图', '样例', mode='paper', sample=True)","source":"def build_heatmap_figure():\n    \"\"\"蓝白暖棕红标注热图：围绕明确基准比较方案—指标矩阵。\"\"\"\n    matrix = np.asarray(\n        (\n            (0.82, 0.68, 0.74, 0.79, 0.71),\n            (0.76, 0.85, 0.69, 0.73, 0.80),\n            (0.69, 0.77, 0.88, 0.81, 0.75),\n            (0.84, 0.72, 0.76, 0.70, 0.86),\n            (0.73, 0.81, 0.79, 0.87, 0.78),\n        )\n    )\n    fig, ax = new_fig(\n        width=\"full\",\n        ratio=1.0,\n        mode=MODE,\n        preserve_canvas=True,\n    )\n    comparison_reference = 0.78\n    mesh, _ = plot_annotated_heatmap(\n        ax,\n        matrix,\n        (\"经济\", \"可靠\", \"公平\", \"低碳\", \"实施\"),\n        (\"方案甲\", \"方案乙\", \"方案丙\", \"方案丁\", \"方案戊\"),\n        kind=\"diverging\",\n        center=comparison_reference,\n        value_format=\".2f\",\n        x_rotation=25.0,\n        square_cells=True,\n    )\n    ax.set_xlabel(\"评价指标\")\n    ax.set_ylabel(\"候选方案\")\n    colorbar = add_continuous_colorbar(\n        fig,\n        mesh,\n        ax,\n        label=\"指标得分（0–1）\",\n        fraction=0.046,\n    )\n    # 比较基准要在色条上自明：diverging 色带的中性位置若只写在图注，\n    # 读者看图时无从判断\"白色代表什么\"。基准并入刻度标签，避免与刻度文字打架\n    colorbar_ticks = np.linspace(float(matrix.min()), float(matrix.max()), 5)\n    colorbar.set_ticks(colorbar_ticks)\n    colorbar.set_ticklabels([\n        f\"{tick:.2f} 基准\" if np.isclose(tick, comparison_reference) else f\"{tick:.2f}\"\n        for tick in colorbar_ticks\n    ])\n    colorbar.ax.axhline(\n        comparison_reference,\n        color=SEMANTIC[\"高对比文字\"], linewidth=1.0, zorder=ZORDER[\"标注\"],\n    )\n    _set_caption(\n        fig,\n        \"构造算例用热图比较五个候选方案在五项已同向归一化指标上的得分。0.78 是样例中\"\n        \"预先声明的比较基准，蓝色表示低于基准、白色接近基准、暖棕红表示高于基准；\"\n        \"矩阵和单元格均保持正方形，单元格保留原始得分以支持精确读取，\"\n        \"所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-heatmap.png","helpers":[{"name":"add_continuous_colorbar","signature":"add_continuous_colorbar(fig, mappable: Any, ax, *, label: str, max_ticks: int=5, fraction: float=0.043, pad: float=0.025, shrink: float=1.0, cax: Any | None=None, orientation: Literal['vertical', 'horizontal'] | None=None)"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_annotated_heatmap","signature":"plot_annotated_heatmap(ax, values: Sequence[Sequence[float]] | np.ndarray, x_labels: Sequence[str], y_labels: Sequence[str], *, kind: ContinuousKind, center: float=0.0, value_format: str='+.2f', x_rotation: float=0.0, origin: Literal['upper', 'lower']='upper', annotate: bool=True, fontsize: float | None=None, square_cells: bool=False, domain: Sequence[float] | None=None, domain_basis: str='')"}]},{"id":"local-pareto","chartTypeZh":"多目标可行集与 Pareto 前沿","builder":"build_pareto_figure","builderSignature":"build_pareto_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"提供真实可行候选 x/y、每目标 min/max 方向及可选风险颜色；用 plot_pareto_front 画二维非支配边界。","scientificBoundary":"只从给定样本筛选非支配点，不证明全局 Pareto 最优；折中点必须说明选择规则。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["scatter-simple","parallel-simple"],"title":"多目标方案Pareto前沿","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_pareto_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_pareto_figure()\nsave_fig(fig, '多目标方案Pareto前沿', '样例', mode='paper', sample=True)","source":"def build_pareto_figure():\n    \"\"\"Pareto 前沿：展示可行集、非支配边界与折中解。\"\"\"\n    rng = np.random.default_rng(20260826)\n    frontier_x = np.linspace(42.0, 122.0, 45)\n    frontier_y = 54.0 + 0.56 * (frontier_x - 42.0) - 0.0017 * (frontier_x - 82.0) ** 2\n    cloud_x = rng.uniform(45.0, 122.0, 720)\n    envelope = np.interp(cloud_x, frontier_x, frontier_y)\n    cloud_y = envelope - rng.gamma(2.2, 3.0, cloud_x.size)\n    cost = np.concatenate((frontier_x, cloud_x))\n    benefit = np.concatenate((frontier_y, cloud_y))\n    robustness = np.clip(0.55 + 0.003 * (benefit - 55.0) + rng.normal(0.0, 0.05, cost.size), 0.35, 0.96)\n    fig, ax = new_fig(width=\"full\", ratio=0.54, mode=MODE)\n    candidates, _, _, _ = plot_pareto_front(\n        ax,\n        cost,\n        benefit,\n        x_direction=\"min\",\n        y_direction=\"max\",\n        color_values=robustness,\n        highlight_index=22,\n        candidate_label=\"可行方案\",\n        frontier_label=\"Pareto 前沿\",\n        highlight_label=\"折中方案\",\n    )\n    add_continuous_colorbar(fig, candidates, ax, label=\"鲁棒得分（0–1）\")\n    ax.set_xlabel(\"成本（万元）\")\n    ax.set_ylabel(\"综合效益（分）\")\n    ax.legend(loc=\"lower right\", frameon=False)\n    _set_caption(\n        fig,\n        \"构造算例展示 765 个可行方案的成本—效益权衡。黑线为按成本最小、效益最大方向\"\n        \"计算的非支配前沿，菱形为前沿上的折中方案，点色编码鲁棒得分；所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-pareto.png","helpers":[{"name":"add_continuous_colorbar","signature":"add_continuous_colorbar(fig, mappable: Any, ax, *, label: str, max_ticks: int=5, fraction: float=0.043, pad: float=0.025, shrink: float=1.0, cax: Any | None=None, orientation: Literal['vertical', 'horizontal'] | None=None)"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_pareto_front","signature":"plot_pareto_front(ax, x: Sequence[float] | np.ndarray, y: Sequence[float] | np.ndarray, *, x_direction: Literal['min', 'max']='min', y_direction: Literal['min', 'max']='max', color_values: Sequence[float] | np.ndarray | None=None, color_kind: ContinuousKind='sequential', color_center: float=0.0, highlight_index: int | None=None, candidate_label: str='可行方案', frontier_label: str='Pareto 前沿', highlight_label: str='折中方案')"}]},{"id":"local-sensitivity","chartTypeZh":"有符号敏感性排序条形图","builder":"build_sensitivity_figure","builderSignature":"build_sensitivity_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"以参数名与相同扰动口径计算的 effects 调用 plot_sensitivity_bars。","scientificBoundary":"只负责排序绘制，不计算模型敏感性；局部单因素扰动不等于全局重要性。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":[],"title":"因素敏感性排序","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_sensitivity_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_sensitivity_figure()\nsave_fig(fig, '因素敏感性排序', '样例', mode='paper', sample=True)","source":"def build_sensitivity_figure():\n    \"\"\"龙卷风灵敏度条形图：排序有符号影响。\"\"\"\n    labels = (\"需求规模\", \"单位成本\", \"服务能力\", \"时间窗\", \"碳价\", \"库存上限\", \"惩罚系数\")\n    effects = np.asarray((9.2, -7.4, 6.1, 3.8, -3.2, 1.7, -1.1))\n    fig, ax = new_fig(width=\"full\", ratio=0.52, mode=MODE)\n    plot_sensitivity_bars(ax, labels, effects, sort_by_magnitude=True)\n    ax.set_xlabel(\"目标函数变化（%）\")\n    ax.set_ylabel(\"扰动因素\")\n    _set_caption(\n        fig,\n        \"构造算例比较七个参数在同幅度单因素扰动下引起的目标函数变化。条形长度表示影响\"\n        \"绝对值，左右方向表示增减；排序只反映局部敏感性，不等同于因果重要性，\"\n        \"所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-sensitivity.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_sensitivity_bars","signature":"plot_sensitivity_bars(ax, labels: Sequence[str], effects: Sequence[float] | np.ndarray, *, sort_by_magnitude: bool=True)"}]},{"id":"local-feature-attribution","chartTypeZh":"模型特征归因蜂群图","builder":"build_feature_attribution_figure","builderSignature":"build_feature_attribution_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"n×p 的 attributions/feature_values 与 p 个特征名；用 plot_feature_attribution_beeswarm 说明归因及特征值依据。","scientificBoundary":"绘图不计算 SHAP；现例归因为合成线性与交互项，颜色为每特征内归一化高低。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["scatter-simple"],"title":"模型特征归因蜂群图","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_feature_attribution_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_feature_attribution_figure()\nsave_fig(fig, '模型特征归因蜂群图', '样例', mode='paper', sample=True)","source":"def build_feature_attribution_figure():\n    \"\"\"特征归因蜂群：同时展示逐样本方向、幅度、密度与特征取值。\"\"\"\n    rng = np.random.default_rng(20260826)\n    feature_names = (\n        \"需求规模\",\n        \"单位成本\",\n        \"服务能力\",\n        \"平均距离\",\n        \"时间窗紧度\",\n        \"碳排因子\",\n        \"库存水平\",\n        \"天气风险\",\n    )\n    feature_values = rng.normal(0.0, 1.0, size=(260, len(feature_names)))\n    effect = np.asarray((5.6, -4.8, 4.1, -3.5, -3.0, -2.4, 1.8, -1.4))\n    interaction = 0.75 * feature_values[:, [0]] * feature_values[:, [4]]\n    attributions = feature_values * effect + rng.normal(\n        0.0,\n        0.55,\n        size=feature_values.shape,\n    )\n    attributions[:, [0, 4]] += interaction\n\n    fig, ax = new_fig(width=\"full\", ratio=0.56, mode=MODE)\n    plot_feature_attribution_beeswarm(\n        ax,\n        attributions,\n        feature_values,\n        feature_names,\n        attribution_basis=(\n            \"构造数据：按预设局部响应、交互项和随机扰动生成逐样本示例 SHAP 值；\"\n            \"不是任何真实模型的解释结果\"\n        ),\n        feature_value_basis=\"构造的 260 个标准化方案输入；颜色在每个特征内部做最小—最大归一化\",\n        max_features=8,\n    )\n    ax.set_xlabel(\"对综合效益预测的示例 SHAP 归因值（分）\")\n    ax.set_ylabel(\"输入特征\")\n    _set_caption(\n        fig,\n        \"构造算例展示 260 个方案样本的逐样本 SHAP 归因。横向位置表示对综合效益预测的\"\n        \"正负贡献及幅度，行顺序按平均绝对归因排序，点色表示各特征内部取值由低到高，\"\n        \"纵向展开仅为防重叠和展示密度；该图不证明因果，所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-feature-attribution.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_feature_attribution_beeswarm","signature":"plot_feature_attribution_beeswarm(ax, attributions: Sequence[Sequence[float]] | np.ndarray, feature_values: Sequence[Sequence[float]] | np.ndarray, feature_names: Sequence[str], *, attribution_basis: str, feature_value_basis: str, max_features: int=10, seed: int=20260826)"}]},{"id":"local-reference-context","chartTypeZh":"响应曲线、参考区间与参考谱","builder":"build_reference_context_figure","builderSignature":"build_reference_context_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"主曲线、已定义参考区间及独立参考谱；add_reference_span 和 plot_reference_underlay 均说明 basis。","scientificBoundary":"参考谱被单独归一化到 [0,1]，只能比较峰位/形状，不能借主轴读它的绝对量。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple"],"title":"达标区间内的响应曲线","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_reference_context_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_reference_context_figure()\nsave_fig(fig, '达标区间内的响应曲线', '样例', mode='paper', sample=True)","source":"def build_reference_context_figure():\n    \"\"\"语义参考带与归一化参考谱：比较达标窗口、峰位与形态。\"\"\"\n    wavelength = np.linspace(430.0, 680.0, 180)\n    main_response = (\n        0.82 * np.exp(-0.5 * ((wavelength - 552.0) / 34.0) ** 2)\n        + 0.18 * np.exp(-0.5 * ((wavelength - 610.0) / 52.0) ** 2)\n    )\n    main_response /= float(np.max(main_response))\n    reference_spectrum = (\n        1.15 * np.exp(-0.5 * ((wavelength - 540.0) / 27.0) ** 2)\n        + 0.22 * np.exp(-0.5 * ((wavelength - 600.0) / 45.0) ** 2)\n    )\n\n    fig, ax = new_fig(width=\"full\", ratio=0.50, mode=MODE)\n    add_reference_span(\n        ax,\n        ((520.0, 570.0),),\n        label=\"题面给定有效波段\",\n        basis=\"构造题面规定的 520～570 nm 有效波段；只作语义窗口\",\n    )\n    plot_reference_underlay(\n        ax,\n        wavelength,\n        reference_spectrum,\n        label=\"附件基准谱（归一化）\",\n        basis=\"构造附件实测基准谱，按自身最小值—最大值归一化到 [0, 1]\",\n    )\n    ax.plot(\n        wavelength,\n        main_response,\n        color=SEMANTIC[\"主推模型\"],\n        linewidth=1.45,\n        label=\"当前方案响应（归一化）\",\n        zorder=ZORDER[\"主线\"],\n    )\n    ax.set_xlabel(\"波长（nm）\")\n    ax.set_ylabel(\"归一化响应（0–1）\")\n    ax.legend(loc=\"upper right\", frameon=False)\n    apply_data_limits(ax, wavelength, main_response)\n    _set_caption(\n        fig,\n        \"构造算例检查当前方案的主响应是否落入题面规定的 520～570 nm 有效波段，并与\"\n        \"附件基准谱比较峰位和形态。蓝色背景仅表示题面窗口，不是置信区间；灰色参考谱和\"\n        \"主响应分别按自身极值归一化到 [0, 1]，参考层固定在数据层下且不参与坐标范围计算。\"\n        \"该图只支持形态与窗口关系判断，所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-reference-context.png","helpers":[{"name":"add_reference_span","signature":"add_reference_span(ax: Any, spans: Sequence[Sequence[float]] | np.ndarray, *, orient: Literal['x', 'y']='x', label: str, basis: str, alpha: float=0.16)"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_reference_underlay","signature":"plot_reference_underlay(ax: Any, x: Sequence[float] | np.ndarray, y: Sequence[float] | np.ndarray, *, label: str, basis: str, alpha: float=0.22)"}]},{"id":"local-ordered-parameter-scan","chartTypeZh":"有序参数扫描曲线族","builder":"build_ordered_parameter_scan_figure","builderSignature":"build_ordered_parameter_scan_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"共同 x、每参数档一行的 y_series 与数值 ordered_by；plot_line_series 稳定排序并使用有序色阶。","scientificBoundary":"1–8 档为受控展示范围；不能因排序或平滑隐藏不利曲线。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple"],"title":"参数扫描下的响应曲线族","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_ordered_parameter_scan_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_ordered_parameter_scan_figure()\nsave_fig(fig, '参数扫描下的响应曲线族', '样例', mode='paper', sample=True)","source":"def build_ordered_parameter_scan_figure():\n    \"\"\"有序参数扫描：以单调色阶展示响应曲线族的系统迁移。\"\"\"\n    resource = np.linspace(0.0, 10.0, 90)\n    levels = np.asarray((0.50, 0.75, 1.00, 1.25, 1.50, 1.75))\n    responses = np.vstack(\n        [\n            level * (1.0 - np.exp(-resource / (1.8 + 0.45 * level)))\n            for level in levels\n        ]\n    )\n    labels = tuple(f\"系数 {level:.2f}\" for level in levels)\n\n    fig, ax = new_fig(width=\"full\", ratio=0.50, mode=MODE)\n    plot_line_series(\n        ax,\n        resource,\n        responses,\n        labels,\n        direct_labels=False,\n        ordered_by=levels,\n    )\n    ax.legend(\n        handles=tuple(ax.lines),\n        labels=labels,\n        title=\"响应系数（无量纲）\",\n        loc=\"best\",\n        frameon=False,\n    )\n    ax.set_xlabel(\"资源投入（标准化单位）\")\n    ax.set_ylabel(\"系统响应（标准化单位）\")\n    apply_data_limits(ax, resource, responses.ravel())\n    _set_caption(\n        fig,\n        \"构造算例比较同一系统响应随六档参数由低到高的整体迁移与边际效应。颜色从暗到亮\"\n        \"严格对应响应系数从 0.50 增至 1.75，图例按数值升序；全部曲线统一实线且不使用\"\n        \"不同 marker，颜色只表达顺序而不代替参数数值。所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-ordered-parameter-scan.png","helpers":[{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"},{"name":"plot_line_series","signature":"plot_line_series(ax, x: Sequence[float] | np.ndarray, y_series: Sequence[Sequence[float]] | np.ndarray, labels: Sequence[str], *, direct_labels: bool=True, include_markers: bool=True, ordered_by: Sequence[float] | np.ndarray | None=None, focal_label: str | None=None, linewidth: float | None=None, markersize: float | None=None)"}]},{"id":"local-zoom-inset","chartTypeZh":"同源曲线局部放大","builder":"build_zoom_inset_figure","builderSignature":"build_zoom_inset_figure()","sourceRelativePath":"绘图样式/生成图型能力样例库.py","inputAdaptation":"主图完整 x 和所有同序列曲线；add_zoom_inset 显式窗口与选择依据，复用主图编码。","scientificBoundary":"内嵌图不能漏系列、换数据或用裁切制造差异；主图保留完整范围。","dataStatus":"构造数据；仅图型与版式示例，不是实际比赛结果","relatedEChartsIds":["line-simple"],"title":"重叠曲线的局部放大对照","invocation":"# 解压通用代码包后，在“绘图样式”目录中运行本段。\n# 这是构造数据演示；真实数据须先按本卡片说明适配。\nimport os\nfrom pathlib import Path\nfrom 生成图型能力样例库 import build_zoom_inset_figure\nfrom plot_utils import save_fig\nos.environ['CUMCM_FIGURE_ROOT'] = str(Path('演示输出').resolve())\nfig = build_zoom_inset_figure()\nsave_fig(fig, '重叠曲线的局部放大对照', '样例', mode='paper', sample=True)","source":"def build_zoom_inset_figure():\n    \"\"\"同源局部放大：在不改变主轴范围时读出重叠曲线的微小差异。\"\"\"\n    control = np.linspace(0.0, 10.0, 121)\n    base = 0.72 + 0.12 / (1.0 + np.exp(-(control - 5.0)))\n    responses = (\n        base,\n        base + 0.0030 * np.exp(-((control - 5.0) / 1.2) ** 2),\n        base - 0.0022 * np.exp(-((control - 5.0) / 1.2) ** 2),\n    )\n    labels = (\"方案甲\", \"方案乙\", \"方案丙\")\n\n    fig, ax = new_fig(width=\"full\", ratio=0.50, mode=MODE)\n    encodings = series_encoding_map(labels, include_marker=False)\n    for label, values in zip(labels, responses, strict=True):\n        ax.plot(\n            control,\n            values,\n            linewidth=1.25,\n            label=label,\n            zorder=ZORDER[\"主线\"],\n            **encodings[label],\n        )\n    ax.set_xlabel(\"控制参数（无量纲）\")\n    ax.set_ylabel(\"系统响应（无量纲）\")\n    ax.legend(loc=\"upper left\", frameon=False)\n    apply_data_limits(ax, control, np.concatenate(responses))\n    add_zoom_inset(\n        ax,\n        tuple((control, values) for values in responses),\n        x_window=(4.4, 5.6),\n        basis=\"构造算例的拐点邻域内三方案差值小于主图线宽，需同源放大辨认\",\n    )\n    _set_caption(\n        fig,\n        \"构造算例比较三种方案的全局响应与拐点邻域微小差异。主轴保持完整数据范围；\"\n        \"内嵌轴只重画主图同一批数据，放大 4.4～5.6 的拐点邻域，原因是该区间内\"\n        \"三方案差值小于主图线宽。放大纵窗覆盖横窗内全部曲线，框线与连接线随窗口\"\n        \"自动联动；所有数值均为示例。\",\n    )\n    return fig","preview":"assets/workflow/local-zoom-inset.png","helpers":[{"name":"add_zoom_inset","signature":"add_zoom_inset(ax: Any, series: Sequence[Sequence[Sequence[float] | np.ndarray]], *, x_window: Sequence[float], basis: str, y_window: Sequence[float] | None=None, bounds: Sequence[float]=(0.58, 0.13, 0.34, 0.3), connector_corners: Sequence[int] | None=None)"},{"name":"new_fig","signature":"new_fig(width: Literal['full', 'half']='full', ratio: float=0.618, mode: Mode='paper', font_mode: FontMode='song', preserve_canvas: bool=False, layout: Literal['none', 'constrained'] | None=None)"}]}]}