evalrx 0.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. evalrx/__init__.py +139 -0
  2. evalrx/agent_assets/__init__.py +2 -0
  3. evalrx/agent_assets/skills/README.md +28 -0
  4. evalrx/agent_assets/skills/eval-chart-style/SKILL.md +172 -0
  5. evalrx/agent_assets/skills/evalrx-report-ui/SKILL.md +116 -0
  6. evalrx/agent_assets/skills/nature-figure/LICENSE +201 -0
  7. evalrx/agent_assets/skills/nature-figure/README.md +412 -0
  8. evalrx/agent_assets/skills/nature-figure/SKILL.md +60 -0
  9. evalrx/agent_assets/skills/nature-figure/manifest.yaml +59 -0
  10. evalrx/agent_assets/skills/nature-figure/references/api.md +436 -0
  11. evalrx/agent_assets/skills/nature-figure/references/backend-selection.md +100 -0
  12. evalrx/agent_assets/skills/nature-figure/references/chart-types.md +281 -0
  13. evalrx/agent_assets/skills/nature-figure/references/common-patterns.md +350 -0
  14. evalrx/agent_assets/skills/nature-figure/references/demos.md +65 -0
  15. evalrx/agent_assets/skills/nature-figure/references/design-theory.md +439 -0
  16. evalrx/agent_assets/skills/nature-figure/references/figure-contract.md +93 -0
  17. evalrx/agent_assets/skills/nature-figure/references/figure-legend-conventions.md +71 -0
  18. evalrx/agent_assets/skills/nature-figure/references/nature-2026-observations.md +112 -0
  19. evalrx/agent_assets/skills/nature-figure/references/qa-contract.md +119 -0
  20. evalrx/agent_assets/skills/nature-figure/references/r-template-index.md +66 -0
  21. evalrx/agent_assets/skills/nature-figure/references/r-workflow.md +161 -0
  22. evalrx/agent_assets/skills/nature-figure/references/tutorials.md +251 -0
  23. evalrx/agent_assets/skills/nature-figure/static/core/contract.md +29 -0
  24. evalrx/agent_assets/skills/nature-figure/static/core/stance.md +37 -0
  25. evalrx/agent_assets/skills/nature-figure/static/fragments/backend/python.md +37 -0
  26. evalrx/agent_assets/skills/nature-figure/static/fragments/backend/r.md +44 -0
  27. evalrx/agent_assets/skills/outcome-driver-analysis/SKILL.md +213 -0
  28. evalrx/agent_assets/skills/outcome-driver-analysis/assets/analysis_report_template.md +53 -0
  29. evalrx/agent_assets/skills/outcome-driver-analysis/references/model_selection.md +72 -0
  30. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/explanatory_var_eda.R +130 -0
  31. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/explanatory_var_eda.py +150 -0
  32. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/fit_outcome_model.R +181 -0
  33. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/fit_outcome_model.py +186 -0
  34. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/univariate_eda.R +149 -0
  35. evalrx/agent_assets/skills/outcome-driver-analysis/scripts/univariate_eda.py +177 -0
  36. evalrx/agent_assets/skills.py +27 -0
  37. evalrx/agent_runtime/__init__.py +78 -0
  38. evalrx/agent_runtime/_docker_runner.py +89 -0
  39. evalrx/agent_runtime/cli_runtime.py +103 -0
  40. evalrx/agent_runtime/cli_transcript.py +138 -0
  41. evalrx/agent_runtime/cli_types.py +68 -0
  42. evalrx/agent_runtime/codegen/__init__.py +5 -0
  43. evalrx/agent_runtime/codegen/runner.py +94 -0
  44. evalrx/agent_runtime/experiment_harness.py +117 -0
  45. evalrx/agent_runtime/factory.py +102 -0
  46. evalrx/agent_runtime/json_shape.py +44 -0
  47. evalrx/agent_runtime/judges/__init__.py +28 -0
  48. evalrx/agent_runtime/judges/agy.py +179 -0
  49. evalrx/agent_runtime/judges/autodetect.py +135 -0
  50. evalrx/agent_runtime/judges/claude.py +159 -0
  51. evalrx/agent_runtime/judges/codex.py +120 -0
  52. evalrx/agent_runtime/providers/__init__.py +21 -0
  53. evalrx/agent_runtime/providers/antigravity.py +31 -0
  54. evalrx/agent_runtime/providers/base.py +145 -0
  55. evalrx/agent_runtime/providers/claude_code.py +49 -0
  56. evalrx/agent_runtime/providers/codex.py +37 -0
  57. evalrx/agent_runtime/providers/gemini_cli.py +26 -0
  58. evalrx/agent_runtime/providers/kimi_cli.py +27 -0
  59. evalrx/agent_runtime/providers/opencode.py +27 -0
  60. evalrx/agent_runtime/providers/registry.py +58 -0
  61. evalrx/agent_runtime/sandbox.py +517 -0
  62. evalrx/agent_runtime/skill_audit.py +143 -0
  63. evalrx/agent_runtime/skills/__init__.py +19 -0
  64. evalrx/agent_runtime/skills/installer.py +68 -0
  65. evalrx/agent_runtime/skills/prompt_policy.py +86 -0
  66. evalrx/agent_runtime/skills/resolver.py +19 -0
  67. evalrx/analysis/__init__.py +132 -0
  68. evalrx/analysis/adjudicate.py +154 -0
  69. evalrx/analysis/analysis_module.py +361 -0
  70. evalrx/analysis/api.py +171 -0
  71. evalrx/analysis/case_studio.py +651 -0
  72. evalrx/analysis/cli.py +114 -0
  73. evalrx/analysis/dashboard.py +350 -0
  74. evalrx/analysis/eval_case_matrix.py +118 -0
  75. evalrx/analysis/eval_viz_theme.py +833 -0
  76. evalrx/analysis/explore_run.py +333 -0
  77. evalrx/analysis/explorer.py +1276 -0
  78. evalrx/analysis/failure_modes.py +607 -0
  79. evalrx/analysis/fused_pipeline.py +489 -0
  80. evalrx/analysis/holdout.py +300 -0
  81. evalrx/analysis/hypothesis_agent.py +230 -0
  82. evalrx/analysis/narration.py +177 -0
  83. evalrx/analysis/operationalize.py +442 -0
  84. evalrx/analysis/plain_language.py +42 -0
  85. evalrx/analysis/planner.py +283 -0
  86. evalrx/analysis/probe_search.py +203 -0
  87. evalrx/analysis/profile.py +268 -0
  88. evalrx/analysis/prompts/__init__.py +0 -0
  89. evalrx/analysis/prompts/explorer.py +417 -0
  90. evalrx/analysis/prompts/failure_modes.py +33 -0
  91. evalrx/analysis/prompts/holdout.py +27 -0
  92. evalrx/analysis/prompts/hypothesis_agent.py +78 -0
  93. evalrx/analysis/prompts/run_codebase.py +47 -0
  94. evalrx/analysis/prompts/stats_agent.py +72 -0
  95. evalrx/analysis/prompts/stats_tool_generator.py +43 -0
  96. evalrx/analysis/result_marker.py +47 -0
  97. evalrx/analysis/run_codebase.py +242 -0
  98. evalrx/analysis/run_view.py +205 -0
  99. evalrx/analysis/stage_views.py +93 -0
  100. evalrx/analysis/stats_agent.py +944 -0
  101. evalrx/analysis/stats_tool_agent.py +261 -0
  102. evalrx/analysis/stats_tool_generator.py +415 -0
  103. evalrx/analysis/stats_tools.py +1153 -0
  104. evalrx/analysis/trajectory_records.py +193 -0
  105. evalrx/analysis/workbench.py +431 -0
  106. evalrx/analyzers/__init__.py +42 -0
  107. evalrx/analyzers/agent/__init__.py +25 -0
  108. evalrx/analyzers/agent/counterfactual.py +84 -0
  109. evalrx/analyzers/agent/first_error_judge.py +96 -0
  110. evalrx/analyzers/agent/ignored_obs.py +81 -0
  111. evalrx/analyzers/agent/loop_detect.py +79 -0
  112. evalrx/analyzers/agent/reliability.py +165 -0
  113. evalrx/analyzers/agent/tool_shap.py +225 -0
  114. evalrx/analyzers/agent/trajectory_rubric.py +168 -0
  115. evalrx/analyzers/attention/__init__.py +19 -0
  116. evalrx/analyzers/attention/relative_attn.py +610 -0
  117. evalrx/analyzers/attention/rollout.py +73 -0
  118. evalrx/analyzers/attention/sink.py +56 -0
  119. evalrx/analyzers/attention/summary.py +190 -0
  120. evalrx/analyzers/attribution/__init__.py +6 -0
  121. evalrx/analyzers/attribution/generic_attn.py +31 -0
  122. evalrx/analyzers/attribution/gradcam.py +30 -0
  123. evalrx/analyzers/base.py +12 -0
  124. evalrx/analyzers/geometry/__init__.py +6 -0
  125. evalrx/analyzers/geometry/cka.py +70 -0
  126. evalrx/analyzers/geometry/linear_probe.py +157 -0
  127. evalrx/analyzers/hallucination/__init__.py +9 -0
  128. evalrx/analyzers/hallucination/chair.py +78 -0
  129. evalrx/analyzers/hallucination/opera.py +29 -0
  130. evalrx/analyzers/hallucination/pope.py +119 -0
  131. evalrx/analyzers/hallucination/selfcheck.py +155 -0
  132. evalrx/analyzers/hallucination/vcd.py +29 -0
  133. evalrx/analyzers/lens/__init__.py +7 -0
  134. evalrx/analyzers/lens/layer_contrast.py +133 -0
  135. evalrx/analyzers/lens/logit_lens.py +138 -0
  136. evalrx/analyzers/lens/tuned_lens.py +30 -0
  137. evalrx/analyzers/patching/__init__.py +5 -0
  138. evalrx/analyzers/patching/causal_trace.py +30 -0
  139. evalrx/analyzers/perturbation/__init__.py +23 -0
  140. evalrx/analyzers/perturbation/_shapley.py +54 -0
  141. evalrx/analyzers/perturbation/context_shap.py +174 -0
  142. evalrx/analyzers/perturbation/cot_faithfulness.py +239 -0
  143. evalrx/analyzers/perturbation/format_sensitivity.py +237 -0
  144. evalrx/analyzers/perturbation/mm_shap.py +146 -0
  145. evalrx/analyzers/perturbation/modality_ablation.py +196 -0
  146. evalrx/analyzers/perturbation/perturbation_battery.py +274 -0
  147. evalrx/analyzers/perturbation/prompt_contrast.py +265 -0
  148. evalrx/analyzers/perturbation/rise.py +94 -0
  149. evalrx/analyzers/perturbation/vl_shap.py +102 -0
  150. evalrx/analyzers/reasoning/__init__.py +33 -0
  151. evalrx/analyzers/reasoning/_text.py +328 -0
  152. evalrx/analyzers/reasoning/answer_extraction_audit.py +327 -0
  153. evalrx/analyzers/reasoning/arith_audit.py +226 -0
  154. evalrx/analyzers/reasoning/contamination.py +214 -0
  155. evalrx/analyzers/reasoning/knowledge_split.py +253 -0
  156. evalrx/analyzers/reasoning/self_repair.py +246 -0
  157. evalrx/analyzers/reasoning/step_rollout_value.py +216 -0
  158. evalrx/analyzers/reasoning/termination_audit.py +258 -0
  159. evalrx/analyzers/uncertainty/__init__.py +18 -0
  160. evalrx/analyzers/uncertainty/calibration.py +174 -0
  161. evalrx/analyzers/uncertainty/coverage_gap.py +199 -0
  162. evalrx/analyzers/uncertainty/entropy.py +90 -0
  163. evalrx/analyzers/uncertainty/logprob_entropy.py +69 -0
  164. evalrx/analyzers/uncertainty/self_consistency.py +204 -0
  165. evalrx/analyzers/uncertainty/verbalized_conf.py +64 -0
  166. evalrx/cli.py +411 -0
  167. evalrx/config.py +77 -0
  168. evalrx/contract/__init__.py +179 -0
  169. evalrx/contract/common.py +452 -0
  170. evalrx/contract/emit.py +948 -0
  171. evalrx/contract/export.py +237 -0
  172. evalrx/contract/m1.py +325 -0
  173. evalrx/contract/m2.py +317 -0
  174. evalrx/contract/m3.py +165 -0
  175. evalrx/contract/m4.py +130 -0
  176. evalrx/contract/m5.py +292 -0
  177. evalrx/contract/methodology.py +76 -0
  178. evalrx/contract/pre_m1.py +58 -0
  179. evalrx/contract/typescript.py +140 -0
  180. evalrx/core/__init__.py +85 -0
  181. evalrx/core/analyzer.py +174 -0
  182. evalrx/core/capability.py +54 -0
  183. evalrx/core/case.py +443 -0
  184. evalrx/core/experiment.py +106 -0
  185. evalrx/core/model.py +198 -0
  186. evalrx/core/pipeline.py +42 -0
  187. evalrx/core/registry.py +142 -0
  188. evalrx/core/result.py +64 -0
  189. evalrx/core/spec.py +173 -0
  190. evalrx/core/tokentype.py +165 -0
  191. evalrx/core/tool.py +92 -0
  192. evalrx/datasets/__init__.py +41 -0
  193. evalrx/datasets/base.py +68 -0
  194. evalrx/datasets/gui_os.py +52 -0
  195. evalrx/datasets/llm_qa.py +57 -0
  196. evalrx/datasets/pure_qa.py +12 -0
  197. evalrx/datasets/vlm_qa.py +695 -0
  198. evalrx/datasets/web_search_qa.py +52 -0
  199. evalrx/eval_agent/__init__.py +341 -0
  200. evalrx/eval_agent/_tools.py +81 -0
  201. evalrx/eval_agent/ab_runner.py +50 -0
  202. evalrx/eval_agent/agentic/__init__.py +43 -0
  203. evalrx/eval_agent/agentic/actions.py +216 -0
  204. evalrx/eval_agent/agentic/board.py +107 -0
  205. evalrx/eval_agent/agentic/loop.py +190 -0
  206. evalrx/eval_agent/agentic/tools.py +538 -0
  207. evalrx/eval_agent/checkpoint.py +57 -0
  208. evalrx/eval_agent/cli_agent.py +59 -0
  209. evalrx/eval_agent/cli_skills.py +5 -0
  210. evalrx/eval_agent/evolution.py +396 -0
  211. evalrx/eval_agent/git_manager.py +215 -0
  212. evalrx/eval_agent/hypothesis.py +172 -0
  213. evalrx/eval_agent/label_quarantine.py +209 -0
  214. evalrx/eval_agent/legacy.py +530 -0
  215. evalrx/eval_agent/log_schema.py +497 -0
  216. evalrx/eval_agent/loop.py +2159 -0
  217. evalrx/eval_agent/loop_reports.py +116 -0
  218. evalrx/eval_agent/model_instrumentation.py +282 -0
  219. evalrx/eval_agent/narration.py +193 -0
  220. evalrx/eval_agent/nl_runner.py +460 -0
  221. evalrx/eval_agent/orchestrator.py +61 -0
  222. evalrx/eval_agent/preregister.py +93 -0
  223. evalrx/eval_agent/prompts/__init__.py +1 -0
  224. evalrx/eval_agent/prompts/agentic.py +46 -0
  225. evalrx/eval_agent/prompts/case_discovery.py +25 -0
  226. evalrx/eval_agent/prompts/diagnosis.py +125 -0
  227. evalrx/eval_agent/prompts/experiment_writer.py +265 -0
  228. evalrx/eval_agent/prompts/explore_step.py +37 -0
  229. evalrx/eval_agent/prompts/fix_agent.py +257 -0
  230. evalrx/eval_agent/prompts/hypothesis_tester.py +15 -0
  231. evalrx/eval_agent/prompts/nl_runner.py +38 -0
  232. evalrx/eval_agent/prompts/probe_agent.py +25 -0
  233. evalrx/eval_agent/prompts/probe_candidate_generator.py +14 -0
  234. evalrx/eval_agent/prompts/probe_generator.py +35 -0
  235. evalrx/eval_agent/prompts/whitebox_probe_generator.py +38 -0
  236. evalrx/eval_agent/report.py +58 -0
  237. evalrx/eval_agent/run_context.py +354 -0
  238. evalrx/eval_agent/run_log.schema.json +1215 -0
  239. evalrx/eval_agent/run_logger_v2.py +1764 -0
  240. evalrx/eval_agent/run_metadata.py +208 -0
  241. evalrx/eval_agent/stages/__init__.py +56 -0
  242. evalrx/eval_agent/stages/case_discovery.py +293 -0
  243. evalrx/eval_agent/stages/diagnosis.py +1017 -0
  244. evalrx/eval_agent/stages/experiment_writer.py +1634 -0
  245. evalrx/eval_agent/stages/fix_agent.py +3916 -0
  246. evalrx/eval_agent/stages/fix_internals.py +499 -0
  247. evalrx/eval_agent/stages/fix_pipeline.py +725 -0
  248. evalrx/eval_agent/stages/fix_tiers.py +187 -0
  249. evalrx/eval_agent/stages/fix_tools.py +1034 -0
  250. evalrx/eval_agent/stages/hypothesis_tester.py +1014 -0
  251. evalrx/eval_agent/stages/probe.py +439 -0
  252. evalrx/eval_agent/stages/probe_agent.py +1079 -0
  253. evalrx/eval_agent/stages/probe_candidate_generator.py +128 -0
  254. evalrx/eval_agent/stages/probe_generator.py +326 -0
  255. evalrx/eval_agent/stages/probe_search_agent.py +106 -0
  256. evalrx/eval_agent/stages/protocol.py +112 -0
  257. evalrx/eval_agent/stages/repair_catalog.py +273 -0
  258. evalrx/eval_agent/stages/surgery.py +524 -0
  259. evalrx/eval_agent/stages/whitebox_probe_generator.py +351 -0
  260. evalrx/eval_agent/store.py +231 -0
  261. evalrx/logging_utils.py +112 -0
  262. evalrx/models/__init__.py +161 -0
  263. evalrx/models/_discover.py +101 -0
  264. evalrx/models/agent.py +380 -0
  265. evalrx/models/backends/__init__.py +58 -0
  266. evalrx/models/backends/api.py +169 -0
  267. evalrx/models/backends/base.py +57 -0
  268. evalrx/models/backends/gemini_compat.py +579 -0
  269. evalrx/models/backends/hf_local.py +2074 -0
  270. evalrx/models/backends/openai_compat.py +301 -0
  271. evalrx/models/backends/vllm_offline.py +116 -0
  272. evalrx/models/base.py +24 -0
  273. evalrx/models/blackbox/__init__.py +4 -0
  274. evalrx/models/blackbox/agent.py +31 -0
  275. evalrx/models/blackbox/base.py +29 -0
  276. evalrx/models/blackbox/gemini.py +279 -0
  277. evalrx/models/blackbox/llm_api.py +17 -0
  278. evalrx/models/blackbox/vlm_api.py +17 -0
  279. evalrx/models/compose.py +66 -0
  280. evalrx/models/inference.py +88 -0
  281. evalrx/models/paper_methods/__init__.py +8 -0
  282. evalrx/models/paper_methods/aad.py +53 -0
  283. evalrx/models/paper_methods/ifcd.py +204 -0
  284. evalrx/models/paper_methods/pai.py +164 -0
  285. evalrx/models/paper_methods/tcd.py +202 -0
  286. evalrx/models/paper_methods/vcd.py +45 -0
  287. evalrx/models/paper_methods/vicrop.py +137 -0
  288. evalrx/models/toolcodec.py +143 -0
  289. evalrx/models/tools/__init__.py +20 -0
  290. evalrx/models/tools/perception.py +300 -0
  291. evalrx/models/tools/visual.py +174 -0
  292. evalrx/models/whitebox/__init__.py +26 -0
  293. evalrx/models/whitebox/agent.py +31 -0
  294. evalrx/models/whitebox/base.py +24 -0
  295. evalrx/models/whitebox/qwen.py +61 -0
  296. evalrx/models/whitebox/qwen2_5_omni.py +29 -0
  297. evalrx/models/whitebox/qwen2_audio.py +25 -0
  298. evalrx/models/whitebox/qwen_omni.py +53 -0
  299. evalrx/models/whitebox/qwen_vl.py +62 -0
  300. evalrx/observability/__init__.py +21 -0
  301. evalrx/observability/envelope.py +122 -0
  302. evalrx/observability/outbox.py +111 -0
  303. evalrx/observability/tracer.py +882 -0
  304. evalrx/reporting/__init__.py +28 -0
  305. evalrx/reporting/case_study.py +947 -0
  306. evalrx/reporting/compiler.py +587 -0
  307. evalrx/reporting/dynamic.py +1882 -0
  308. evalrx/reporting/html_report.py +2225 -0
  309. evalrx/reporting/langfuse_exporter.py +38 -0
  310. evalrx/reporting/langfuse_source.py +155 -0
  311. evalrx/reporting/model.py +151 -0
  312. evalrx/reporting/run_events.py +184 -0
  313. evalrx/reporting/server.py +557 -0
  314. evalrx/reporting/stages.py +58 -0
  315. evalrx/reporting/static_export.py +142 -0
  316. evalrx/reporting/web_dist/index.html +146 -0
  317. evalrx/specs.py +727 -0
  318. evalrx/stats/__init__.py +47 -0
  319. evalrx/stats/api.py +192 -0
  320. evalrx/stats/bootstrap.py +86 -0
  321. evalrx/stats/ebh.py +27 -0
  322. evalrx/stats/evalue.py +98 -0
  323. evalrx/stats/friedman.py +138 -0
  324. evalrx/stats/mcnemar.py +40 -0
  325. evalrx/stats/multiplicity.py +159 -0
  326. evalrx/stats/subset_sampling.py +55 -0
  327. evalrx/term_links.py +43 -0
  328. evalrx/viz/__init__.py +7 -0
  329. evalrx/viz/labels.py +77 -0
  330. evalrx/viz/prompts.py +39 -0
  331. evalrx/viz/renderer.py +590 -0
  332. evalrx/viz/schema.py +36 -0
  333. evalrx/viz/style.py +134 -0
  334. evalrx-0.1.2.dist-info/METADATA +532 -0
  335. evalrx-0.1.2.dist-info/RECORD +339 -0
  336. evalrx-0.1.2.dist-info/WHEEL +5 -0
  337. evalrx-0.1.2.dist-info/entry_points.txt +3 -0
  338. evalrx-0.1.2.dist-info/licenses/LICENSE +121 -0
  339. evalrx-0.1.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,439 @@
1
+ # Nature Figure Design Theory
2
+
3
+ Derived from scripts in the [figures4papers](https://github.com/ChenLiu-1996/figures4papers) repository
4
+ (published in *Nature Machine Intelligence* and top ML/bioinformatics venues).
5
+
6
+ ---
7
+
8
+ ## 1) Typography
9
+
10
+ ### Font stack (priority order)
11
+ - **Nature standard**: `font.family = 'sans-serif'`, `font.sans-serif = ['Arial']`
12
+ - **Fallback stack**: `['Arial', 'Helvetica', 'DejaVu Sans', 'sans-serif']`
13
+ - **Helvetica** (equivalent) also appears in many scripts as `font.family = 'helvetica'`
14
+ - SVG/PDF editable text: always set `svg.fonttype = 'none'`
15
+ - LaTeX math labels: `text.usetex = True` only when LaTeX is installed
16
+
17
+ ### Font size hierarchy
18
+ | Context | font.size | axes.linewidth |
19
+ |---------|-----------|---------------|
20
+ | Journal-final dense multi-panel figure at publication width | 7–9 | 0.8–1.2 |
21
+ | Large comparison bar panels (figsize > 28in wide) | 24 | 3 |
22
+ | Compact subfigures / analytic plots | 15–16 | 2 |
23
+ | Axis labels on large panels | 32–54 (override per-label) | — |
24
+ | In-bar annotations | 32–36 | — |
25
+ | Legend text on large panels | 28–38 | — |
26
+ | Tick labels | 20–36 | — |
27
+
28
+ When targeting the final dimensions of a two-column `Nature` figure page, start smaller than
29
+ slide-sized preview figures. The sampled 2026 papers routinely landed in the `7–9 pt` final-text
30
+ regime for dense composites.
31
+
32
+ ---
33
+
34
+ ## 2) Axes & Spines
35
+
36
+ ```python
37
+ plt.rcParams['axes.spines.right'] = False # always off
38
+ plt.rcParams['axes.spines.top'] = False # always off
39
+ plt.rcParams['legend.frameon'] = False # frameless legends everywhere
40
+ ```
41
+
42
+ - Keep only left + bottom spines — minimalist, Nature-approved.
43
+ - No grid lines by default; use sparse y-ticks to guide the eye.
44
+
45
+ ---
46
+
47
+ ## 3) Color Palette
48
+
49
+ Semantic: blue = proposed method, green = positive variants, red/pink = baselines, neutral = reference/background.
50
+ For dense multi-panel figures, however, **family consistency beats maximal hue separation**.
51
+
52
+ ```python
53
+ # Values synced to the CVD-validated EvalRX dataviz palette (family
54
+ # semantics unchanged; see the notice in README.md). Ramps and the 5
55
+ # chromatic series slots were re-validated with the dataviz checker.
56
+ PALETTE = {
57
+ # Proposed / key method
58
+ "blue_main": "#2a78d6", # blue — hero method (categorical slot 1)
59
+ "blue_secondary": "#6da7ec", # medium blue — second author method
60
+
61
+ # Positive / improvement shades (light → dark, validated ordinal ramp)
62
+ "green_1": "#7ec07e",
63
+ "green_2": "#4ca74b",
64
+ "green_3": "#008300",
65
+
66
+ # Baseline / contrast shades (light → dark, validated ordinal ramp)
67
+ "red_1": "#ee9999",
68
+ "red_2": "#e97675",
69
+ "red_strong": "#e34948",
70
+
71
+ # Neutral support (ink ladder)
72
+ "neutral_light": "#c3c2b7",
73
+ "neutral_mid": "#898781",
74
+ "neutral_dark": "#52514e",
75
+ "neutral_black": "#0b0b0b",
76
+
77
+ # Accent / callout (use sparingly)
78
+ "gold": "#eda100",
79
+ "teal": "#1baf7a",
80
+ "violet": "#4a3aa7",
81
+ "magenta":"#e87ba4",
82
+ }
83
+
84
+ DEFAULT_COLOR_ORDER = [
85
+ "#2a78d6", # blue_main
86
+ "#008300", # green_3
87
+ "#e34948", # red_strong
88
+ "#1baf7a", # teal
89
+ "#4a3aa7", # violet
90
+ "#898781", # neutral_mid — reference/background series only
91
+ ]
92
+ ```
93
+
94
+ ### Unified-family rule (recommended for NMI-style pages)
95
+
96
+ Publication figures should read like **one figure**, not six unrelated plots. Prefer one cool family for
97
+ baselines and one lilac/rose family for the proposed method line.
98
+
99
+ ```python
100
+ PALETTE_NMI_PASTEL = {
101
+ "baseline_dark": "#484878",
102
+ "baseline_mid": "#7884B4",
103
+ "baseline_soft": "#B4C0E4",
104
+ "ours_tiny": "#E4E4F0",
105
+ "ours_base": "#E4CCD8",
106
+ "ours_large": "#F0C0CC",
107
+ "delta_up": "#2E9E44",
108
+ "delta_down": "#E53935",
109
+ }
110
+
111
+ DEFAULT_COLOR_ORDER_NMI_PASTEL = [
112
+ "#484878", # baseline_dark
113
+ "#7884B4", # baseline_mid
114
+ "#B4C0E4", # baseline_soft
115
+ "#E4E4F0", # ours_tiny
116
+ "#E4CCD8", # ours_base
117
+ "#F0C0CC", # ours_large
118
+ ]
119
+ ```
120
+
121
+ Rules:
122
+ 1. Keep related baselines in one cool family.
123
+ 2. Keep `Tiny / Base / Large` or sibling variants in one hero family.
124
+ 3. Reserve green/red for arrows, gains, drops, thresholds, or signed biological direction.
125
+ 4. Never remap the same method to a different hue family in another panel.
126
+ 5. If in doubt, reduce saturation before adding more categories.
127
+
128
+ ### Modality-specific palette discipline from sampled 2026 Nature figures
129
+
130
+ - **Imaging plates**: grayscale context + 1–2 fluorescent accent channels on black.
131
+ - **Schematic/material pages**: derive the palette from the physical objects in the schematic,
132
+ then reuse softened versions of those colors in the support plots.
133
+ - **Clinical composites**: dark baseline/reference series, restrained warm/cool follow-up hues,
134
+ pale background bands in forest plots.
135
+ - **Genomics / systems pages**: neutral grey scaffolds plus a small number of biologically
136
+ meaningful highlight families, often one red and one blue.
137
+
138
+ ### Ablation alpha encoding
139
+ When ablating components of one method, use a **single color with varying alpha**:
140
+ ```python
141
+ color = (0.215686, 0.458824, 0.729412) # blue_secondary as RGB tuple
142
+ alphas = np.linspace(0.2, 1.0, n_variants)
143
+ colors = [(color[0], color[1], color[2], a) for a in alphas]
144
+ # alpha=1.0 → full method, alpha=0.2 → minimal/ablated variant
145
+ ```
146
+
147
+ ---
148
+
149
+ ## 4) Layout and Composition
150
+
151
+ ### Figure sizes
152
+ | Figure type | Typical figsize |
153
+ |-------------|----------------|
154
+ | Journal-width composite page / asymmetric multi-panel | (7.0–7.4, 5.5–7.8) |
155
+ | Multi-metric bar (3–4 metrics + legend) | (28–45, 6–12) |
156
+ | Compact single bar | (9–16, 5–8) |
157
+ | Trend / line multi-panel | (14, 4) or (9, 8) |
158
+ | Heatmap single | (8–20, 5–9) |
159
+ | Radar polar | (12, 10) |
160
+ | 3D / illustration multi-panel | (24, 8) |
161
+
162
+ **Rule**: Width ≈ 3–4× height for comparison bars; prevents vertical crowding and allows left-to-right narrative reading.
163
+
164
+ ### Dedicated legend panel
165
+ For multi-axis figures, the **last subplot is legend-only**:
166
+ ```python
167
+ ax_legend = fig.add_subplot(1, n+1, n+1)
168
+ ax_legend.legend(handles, labels, fontsize=..., loc='center', frameon=False)
169
+ ax_legend.set_axis_off()
170
+ ```
171
+
172
+ ### Dynamic y-axis scaling
173
+ Never use fixed 0–100 when values sit in a narrow band.
174
+ Tighten limits to data range: e.g., `ax.set_ylim([data.min() - margin, data.max() + margin])`.
175
+
176
+ ### Nature page archetypes from sampled 2026 papers
177
+
178
+ `Nature` figures were not uniformly dashboard-like. They repeatedly used a few strong page
179
+ archetypes:
180
+
181
+ | Archetype | Layout signal | Practical rule |
182
+ |-----------|---------------|----------------|
183
+ | Schematic-led composite | One wide story panel with smaller quant panels below | Give the schematic the visual hierarchy; supporting plots should validate, not compete |
184
+ | Dark image plate | Repeated black tiles with fluorescent channels | Use black only inside the image plate region; keep scale bars, gutters, and channel labels high-contrast |
185
+ | Clinical triptych | Top longitudinal row, middle forest row, bottom summary row | Reuse the same column logic across outcomes and put the shared legend above the row |
186
+ | Asymmetric hero layout | One dominant circular/schematic panel plus small support plots | Let one panel span multiple grid cells; equal panel sizes are not required |
187
+
188
+ ### Panel labels and gutters
189
+
190
+ - Use small bold lowercase panel letters near the top-left edge.
191
+ - Keep gutters tight but real; increase spacing when dark and light modalities touch.
192
+ - Leave extra bottom clearance when a dense caption will sit immediately below the figure.
193
+ - Avoid decorative panel boxes. Alignment and whitespace should carry the structure.
194
+
195
+ ### Legend economy and direct labelling
196
+
197
+ - Use direct labels when regions, channels, or line identities are spatially stable.
198
+ - Prefer one shared legend strip above a row rather than repeating legends inside several axes.
199
+ - Dense categorical area plots often read better with embedded text than with a detached legend.
200
+ - If a legend exists, it should usually be frameless and visually quieter than the data.
201
+
202
+ ### X-tick suppression
203
+ When bars represent methods and the legend already names them:
204
+ ```python
205
+ ax.set_xticks([]) # hide x-tick labels; use legend + panel title instead
206
+ ```
207
+
208
+ ---
209
+
210
+ ## 5) Bar Chart Rules
211
+
212
+ ### Vertical bars (comparison)
213
+ ```python
214
+ bars = ax.bar(
215
+ x_positions,
216
+ values,
217
+ yerr=std_values,
218
+ capsize=5,
219
+ color=colors,
220
+ label=method_names,
221
+ edgecolor='black', # sharp separation
222
+ linewidth=1.5,
223
+ )
224
+ ```
225
+
226
+ ### Horizontal bars (ablation)
227
+ ```python
228
+ ax.barh(
229
+ y_positions,
230
+ values,
231
+ xerr=std_values,
232
+ color=[(r, g, b, alpha) for alpha in alphas],
233
+ ecolor='k',
234
+ capsize=5,
235
+ )
236
+ ```
237
+
238
+ ### In-bar value annotation
239
+ Print exact numbers inside or above bars at 32–36pt for readability without a grid:
240
+ ```python
241
+ for bar, value in zip(bars, values):
242
+ luminance = compute_luminance(bar_color)
243
+ textcolor = 'white' if luminance < 128 else 'black'
244
+ ax.text(bar.get_x() + bar.get_width()/2,
245
+ bar.get_height() - 0.10,
246
+ f'{value:.2f}',
247
+ ha='center', va='bottom',
248
+ fontsize=32, color=textcolor)
249
+ ```
250
+
251
+ ### Hatch encoding for print-safe grayscale
252
+ ```python
253
+ hatches = ['/', '\\', '.', 'x', 'o']
254
+ for bar, hatch in zip(bars, hatches):
255
+ bar.set_hatch(hatch)
256
+ ```
257
+
258
+ ### Error bar styling
259
+ ```python
260
+ error_kw = {
261
+ 'elinewidth': 2,
262
+ 'capthick': 2,
263
+ 'capsize': 15,
264
+ }
265
+ ```
266
+
267
+ ---
268
+
269
+ ## 6) Line / Trend Plots
270
+
271
+ - Line width: 2–3pt with controlled alpha.
272
+ - Marker size: 8–12pt circles.
273
+ - For clinical or longitudinal triptychs, place one shared legend above the row rather than repeating it per axis.
274
+ - Fading alpha for temporal progression:
275
+ ```python
276
+ from matplotlib.collections import LineCollection
277
+ alphas = np.linspace(0.3, 0.9, n_segments)
278
+ # build LineCollection with per-segment alpha
279
+ ```
280
+ - `fill_between` for uncertainty bands (keep alpha low: 0.1–0.2).
281
+ - Reference baseline as dashed horizontal line: `ax.axhline(y=..., linestyle='--', alpha=0.3, linewidth=4)`.
282
+ - No grid; sparse y-ticks guide the eye.
283
+
284
+ ---
285
+
286
+ ## 7) Heatmap Rules
287
+
288
+ ```python
289
+ import matplotlib as mpl
290
+
291
+ # Diverging (positive/negative): use Red + Blue colormaps per column direction
292
+ cmap_pos = plt.cm.Reds
293
+ cmap_neg = plt.cm.Blues_r
294
+
295
+ # Masked NaN cells show as white
296
+ cmap.set_bad(color='white')
297
+
298
+ # Normalize per column
299
+ norm = mpl.colors.Normalize(vmin=col_min, vmax=col_max)
300
+
301
+ # Remove frame
302
+ ax.set_frame_on(False)
303
+
304
+ # Remove tick marks, keep labels
305
+ ax.tick_params(axis='x', which='both', bottom=False, top=False, length=0)
306
+ ```
307
+
308
+ Cell text contrast:
309
+ ```python
310
+ r, g, b, _ = cmap(norm(value))
311
+ luminance = 0.299*r + 0.587*g + 0.114*b
312
+ text_color = 'white' if luminance < 0.5 else 'black'
313
+ ```
314
+
315
+ ---
316
+
317
+ ## 8) Radar / Polar Charts
318
+
319
+ - Project: `fig.add_subplot(projection='polar')`.
320
+ - Remove default grid and spines; draw custom spokes and contour polygons.
321
+ - Normalize per-spoke to display range (e.g., 45–90) using per-benchmark tick lists.
322
+ - Use `ax.set_theta_zero_location('N')` to start at top.
323
+ - Legend: `bbox_to_anchor=(1.40, 0.05)` outside right edge.
324
+
325
+ ---
326
+
327
+ ## 9) Export Policy
328
+
329
+ ### SVG is the required primary format
330
+
331
+ SVG preserves editable text (when `svg.fonttype = 'none'`), supports lossless scaling,
332
+ and is required for any figure where text labels may need post-hoc alignment in
333
+ Illustrator or Inkscape. Always save SVG first.
334
+
335
+ ```python
336
+ import os
337
+ os.makedirs('./figures/', exist_ok=True)
338
+ fig.tight_layout(pad=2) # default; use pad=1 for compact multi-panel
339
+
340
+ # ── PRIMARY ── editable vector, text as <text> nodes ─────────────────────────
341
+ fig.savefig('./figures/name.svg', bbox_inches='tight')
342
+
343
+ # ── SECONDARY ── raster for quick preview / submission portals ────────────────
344
+ fig.savefig('./figures/name.png', dpi=300, bbox_inches='tight')
345
+
346
+ plt.close(fig) # always close to free memory
347
+ ```
348
+
349
+ **DPI guide (PNG only)**:
350
+ - `dpi=300` — standard for all figure types.
351
+ - `dpi=600` — dense bar panels with many methods.
352
+
353
+ **Never** use `svg.fonttype = 'path'` (matplotlib default): it converts glyphs to bezier
354
+ curves, breaking text editability. The mandatory three rcParams lines (see api.md) must
355
+ be set before any `savefig` call.
356
+
357
+ ---
358
+
359
+ ## 11) Multi-Panel Information Architecture
360
+
361
+ ### Rule: Every panel must answer a unique scientific question
362
+
363
+ In a multi-panel figure, each panel should be independently informative. Covering one panel must leave a gap that cannot be recovered from the others.
364
+
365
+ **Recommended three-level progression**:
366
+
367
+ | Level | Question answered | Typical encoding |
368
+ |-------|------------------|-----------------|
369
+ | Overview | "What is the landscape?" | Stacked bar, composition |
370
+ | Deviation | "What is distinctive per group?" | Z-score heatmap (diverging cmap) |
371
+ | Relationship | "How do variables co-vary?" | Scatter / bubble plot |
372
+
373
+ ### Anti-redundancy checklist
374
+
375
+ Before finalising:
376
+
377
+ - [ ] Panel b does **not** re-display the same data as panel a in a different visual form
378
+ - [ ] Panel c adds a dimension absent from a and b (e.g., correlation, biological relationship)
379
+ - [ ] Each panel has its own axis-label vocabulary (different x/y quantities)
380
+
381
+ ### Common redundancy traps
382
+
383
+ | Trap | Example | Fix |
384
+ |------|---------|-----|
385
+ | Absolute + absolute | Stacked bar (%) + heatmap of same % | Replace heatmap with z-score deviation |
386
+ | Subset of parent | Tumor-only ranked bar is just one column of the stacked bar | Swap for scatter: tumor % vs. immune % |
387
+ | Two rankings | Two ranked bars on related metrics | Replace one with scatter / bubble |
388
+ | Different chart, same data slice | Pie + stacked bar | Merge or replace one with a relationship plot |
389
+
390
+ ### Z-score deviation heatmap (complement to a composition bar)
391
+
392
+ When panel a shows absolute composition, panel b should show **what is atypical** per group:
393
+
394
+ ```python
395
+ # heat: DataFrame (cohorts × cell-type categories), values in %
396
+ z = (heat - heat.mean(axis=0)) / heat.std(axis=0)
397
+ im = ax.imshow(z.values, cmap="RdBu_r", aspect="auto", vmin=-2.5, vmax=2.5)
398
+ # colorbar label:
399
+ cbar.set_label("Z-score vs pan-cohort mean")
400
+ ```
401
+
402
+ Use `RdBu_r` (red = enriched above average, blue = depleted). This diverging view is orthogonal to the absolute-percentage view in panel a.
403
+
404
+ ### Bubble scatter (complement to both)
405
+
406
+ When a = composition, b = deviation, panel c should reveal **biological co-variation**:
407
+
408
+ ```python
409
+ # x: dominant compartment (e.g., tumor %)
410
+ # y: functional readout (e.g., immune-cell %)
411
+ # size: third variable (e.g., stroma %)
412
+ ax.scatter(x, y, s=stroma * scale, c=colors,
413
+ edgecolors="white", linewidth=0.8, alpha=0.9)
414
+ # Quadrant reference lines at median x and median y
415
+ ax.axvline(np.median(x), lw=1.2, ls="--", color="#767676", alpha=0.6)
416
+ ax.axhline(np.median(y), lw=1.2, ls="--", color="#767676", alpha=0.6)
417
+ ```
418
+
419
+ Label quadrants ("Immune-hot / low tumor", "Immune-desert / high tumor", …) with small grey text.
420
+
421
+ ---
422
+
423
+ ## 10) Reproduction Checklist
424
+
425
+ To match Nature publication standards:
426
+
427
+ - [ ] **MANDATORY first lines**: `font.family='sans-serif'`, `font.sans-serif=['Arial','DejaVu Sans','Liberation Sans']`, `svg.fonttype='none'`
428
+ - [ ] **Save as SVG** (primary). PNG dpi=300 as optional raster preview.
429
+ - [ ] Top and right spines off; frameless legend
430
+ - [ ] Figure architecture chosen intentionally: grid, schematic-led composite, image plate, or asymmetric hero layout
431
+ - [ ] Font size ≥ 16 base; 24 for large bar panels; 32–54 for axis labels on large panels
432
+ - [ ] Colors from blue-green-red-neutral semantic palette
433
+ - [ ] Black background used only for imaging plates, not for ordinary plots
434
+ - [ ] Legends omitted or shared when direct labels or one legend strip read better
435
+ - [ ] Y-limits tightened to data range (not 0–100 when values are 80–95)
436
+ - [ ] X-ticks hidden when methods are named in legend
437
+ - [ ] Legend in dedicated panel or `frameon=False`
438
+ - [ ] `tight_layout(pad=2)` before save
439
+ - [ ] `plt.close(fig)` after save
@@ -0,0 +1,93 @@
1
+ # Figure Contract
2
+
3
+ Use this reference before writing plotting code. The goal is to make the figure
4
+ serve the paper's scientific logic.
5
+
6
+ ## Privacy rule
7
+
8
+ Keep the figure contract user-facing, but keep the working trail private. Do not mention
9
+ private paths, source filenames, internal reference documents, template identifiers, or
10
+ where a private draft came from unless the user explicitly asks for provenance.
11
+
12
+ ## Required contract
13
+
14
+ Create a short contract in working notes or in the response:
15
+
16
+ ```text
17
+ Core conclusion:
18
+ Figure archetype:
19
+ Target journal/output:
20
+ Backend: Python or R
21
+ Final size:
22
+ Panel map:
23
+ a:
24
+ b:
25
+ c:
26
+ Evidence hierarchy:
27
+ hero evidence:
28
+ validation evidence:
29
+ controls/robustness:
30
+ Statistics needed:
31
+ Source data needed:
32
+ Image-integrity notes:
33
+ Reviewer risk:
34
+ ```
35
+
36
+ Do not start from a favorite template. Start from the conclusion, then choose the
37
+ minimum set of panels that make the conclusion clear and defensible.
38
+
39
+ ## Core conclusion rules
40
+
41
+ - The core conclusion should be one sentence with a verb: "Treatment X reduces
42
+ Y by restoring Z", not "Treatment results".
43
+ - Every panel must answer a unique question. If covering a panel would not weaken
44
+ the argument, remove or merge it.
45
+ - Separate primary evidence from supporting evidence. The primary evidence gets
46
+ the hero panel or the clearest axis; controls and robustness panels should be
47
+ visually quieter.
48
+ - If the user provides data but no claim, infer a provisional claim from the data
49
+ request and ask for confirmation before final styling.
50
+
51
+ ## Archetype selection
52
+
53
+ | Archetype | Use when | Hero panel | Supporting panels |
54
+ |---|---|---|---|
55
+ | `quantitative grid` | The claim is mainly numerical comparison | Optional; often a dominant summary metric | Shared axes, aligned scales, compact legends |
56
+ | `schematic-led composite` | A workflow, mechanism, device, or experimental design must be understood first | Left or top schematic, 35-60% of area | 2-4 quantitative validation panels |
57
+ | `image plate + quant` | Microscopy, imaging, histology, spatial overlays, segmentation, or blots lead the evidence | Image plate or representative image | Scale bars, overlays, crops, quantification |
58
+ | `asymmetric mixed-modality figure` | The figure combines schematic, raster images, heatmaps, and quantitative plots | One panel spans rows/columns | Smaller panels ranked by evidence value |
59
+
60
+ ## Panel logic
61
+
62
+ Use this order unless the manuscript story clearly requires another:
63
+
64
+ 1. Establish the system: sample, method, cohort, device, or experimental design.
65
+ 2. Show the main effect or primary comparison.
66
+ 3. Show mechanism or localization.
67
+ 4. Quantify the representative image or qualitative observation.
68
+ 5. Add robustness, controls, subgroup analysis, or sensitivity analysis.
69
+
70
+ For Fig. 1 or a method figure, the first panel often defines the visual vocabulary:
71
+ colors, symbols, workflow direction, sample classes, and scale. Reuse that vocabulary
72
+ through the whole figure and, where possible, through the manuscript.
73
+
74
+ ## Aesthetic integration
75
+
76
+ - Use one neutral family, one signal family, and one accent family.
77
+ - Keep the same condition/method color across all panels.
78
+ - Prefer direct labels for stable line identities, channels, and fixed spatial regions.
79
+ - Use a shared legend area when repeated legends would waste space.
80
+ - Avoid equal-sized panels when the evidence is not equally important.
81
+ - Keep schematic colors and quantitative plot colors related. A schematic-led
82
+ figure should look like one integrated argument, not a pasted collage.
83
+
84
+ ## Reviewer-risk prompts
85
+
86
+ Before finalizing, ask what a skeptical reviewer would challenge:
87
+
88
+ - Is the sample size visible in the legend or source data?
89
+ - Are error bars, intervals, and statistical tests defined?
90
+ - Are axes comparable across panels that invite comparison?
91
+ - Are representative images quantified and traceable to raw files?
92
+ - Are image adjustments global and documented?
93
+ - Could the same conclusion be made from fewer panels?
@@ -0,0 +1,71 @@
1
+ # Figure & Table Legend Conventions (Nat Commun 2025 CS/AI corpus)
2
+
3
+ Use this file when **writing or auditing the legend text** of a figure or table.
4
+ It complements `nature-2026-observations.md`, which covers visual/layout
5
+ archetypes; this file covers the *words* of the caption. Distilled from a 2025
6
+ set of 20 open-access *Nature Communications* computer-science / AI papers
7
+ (legend conventions were consistent across all research articles). **Do not copy
8
+ source wording.**
9
+
10
+ ## Legend structure — the fixed skeleton
11
+
12
+ 1. **`Fig. N | ` + a bold noun-phrase overall title** that names the whole
13
+ figure. Common openers: *Overview of …*, *Comparison of …*, *Performance of
14
+ …*, or a finding phrase. No terminal full stop required on the title.
15
+ 2. **`a / b / c …` panels, each described in present tense, telegraphic style**,
16
+ often subject-less: *"a Comparison of the four EMS paradigms. b Distributions
17
+ of WSIs and patches in the pre-training dataset."*
18
+ 3. **Statistics written into the legend**: sample size `n=`, error type, and
19
+ test — *"mean ± 95% CI (n = 1373) … one-way ANOVA with Tukey correction."*
20
+ 4. **Data-availability boilerplate** at the end: *"Source data are provided as a
21
+ Source Data file."*
22
+
23
+ ## Tense
24
+
25
+ - Visual facts in **present** tense — *"are shown as cyan sticks"*, *"depicts"*.
26
+ - Methods/how-it-was-made in **past** tense — *"was performed"*, *"was adopted
27
+ from"*.
28
+
29
+ ## Self-containment rule
30
+
31
+ A legend must be readable away from the body text. Put colour/shape mappings,
32
+ sample size, and key numeric anchors (PDB id, RMSD, units) into the legend
33
+ itself — *"tRNA-Glu of E. coli (PDB: 2DER chain C). 76 nt, RMSD: 2.88 Å."*;
34
+ *"Grey boxes designate what is defined by the benchmark, and orange boxes
35
+ indicate what is unique to each solution."*
36
+
37
+ ## Advanced: the claim-closing sentence
38
+
39
+ A legend's final sentence may advance an argument rather than only describe —
40
+ *"…indicating that these co-folding models are not predicting poses based on
41
+ physics but rather learning patterns in global structures."* Use sparingly, and
42
+ only when the panel actually supports the inference.
43
+
44
+ ## Review/Perspective legends
45
+
46
+ When a figure aggregates others' published systems, each sub-panel gets a
47
+ one-line characterisation (often past tense, describing prior work) and the
48
+ legend carries an attribution line — *"adapted with permission from refs. 16,17
49
+ … by Springer Nature."* Include the permission/attribution string for any
50
+ adapted panel.
51
+
52
+ ## Table captions
53
+
54
+ Same shape: **`Table N | ` + noun phrase**, with detailed specs pointed to
55
+ Methods — *"Table 1 | … Detailed specifications are provided in the Methods
56
+ section."* Benchmark/framework papers lean on tables (multi-metric results) more
57
+ than figures.
58
+
59
+ ## Length & title limits (consistency with style-guardrails)
60
+
61
+ - Keep a Nature-style legend `<= 300` words.
62
+ - Keep the `Fig. N |` title short and nominal; no numbers/results in the figure
63
+ *title* line (numbers live in the panels and stats).
64
+
65
+ ## 中文图注要点
66
+
67
+ - 结构铁律:`图 N | 加粗名词短语总题` → `a/b/c` 现在时电报式分面 → 统计(n、误差、检验)写进图注 → "Source data are provided as a Source Data file." 套语。
68
+ - 时态:视觉事实用现在时,制作方法用过去时。
69
+ - 自足:颜色/形状映射、样本量、关键数值(PDB/RMSD/单位)都写进图注,使其脱离正文可读。
70
+ - 进阶:图注末句可给一句推断结论,但须确有面板支撑。
71
+ - 综述图注:聚合他人系统时逐子图一句话定性,并标注"adapted with permission from refs… by Springer Nature"授权。