@brainpilot/skills 0.0.6
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.
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
- package/skills/01_Meta-Skills/contribute-skill/SKILL.md +277 -0
- package/skills/01_Meta-Skills/contribute-skills-via-pr/SKILL.md +163 -0
- package/skills/01_Meta-Skills/paper-to-skill/SKILL.md +435 -0
- package/skills/01_Meta-Skills/paper-to-skill/references/extraction-guide.md +286 -0
- package/skills/01_Meta-Skills/paper-to-skill/references/skill-template.md +250 -0
- package/skills/01_Meta-Skills/repo-to-skill/SKILL.md +289 -0
- package/skills/01_Meta-Skills/share-case/SKILL.md +253 -0
- package/skills/01_Meta-Skills/share-usage/README.md +63 -0
- package/skills/01_Meta-Skills/share-usage/SKILL.md +395 -0
- package/skills/01_Meta-Skills/verify-skill/SKILL.md +331 -0
- package/skills/02_Cross-Domain_Foundation/cogsci-power-analysis/SKILL.md +194 -0
- package/skills/02_Cross-Domain_Foundation/cogsci-power-analysis/references/effect-sizes.md +352 -0
- package/skills/02_Cross-Domain_Foundation/cogsci-power-analysis/references/sample-size-guide.md +407 -0
- package/skills/02_Cross-Domain_Foundation/cogsci-statistics/SKILL.md +361 -0
- package/skills/02_Cross-Domain_Foundation/cogsci-statistics/references/common-analyses.md +517 -0
- package/skills/02_Cross-Domain_Foundation/cogsci-visualization/SKILL.md +292 -0
- package/skills/02_Cross-Domain_Foundation/cogsci-visualization/references/plot-recipes.md +709 -0
- package/skills/02_Cross-Domain_Foundation/research-literacy/SKILL.md +286 -0
- package/skills/02_Cross-Domain_Foundation/research-literacy/references/common-assumptions.md +320 -0
- package/skills/02_Cross-Domain_Foundation/research-literacy/references/planning-template.md +143 -0
- package/skills/03_Cognitive_Psychology/alternative-uses-task-designer/SKILL.md +197 -0
- package/skills/03_Cognitive_Psychology/alternative-uses-task-designer/references/instruction-templates.md +60 -0
- package/skills/03_Cognitive_Psychology/cognitive-paradigm-design/SKILL.md +246 -0
- package/skills/03_Cognitive_Psychology/cognitive-paradigm-design/references/classic-paradigms.md +435 -0
- package/skills/03_Cognitive_Psychology/cognitive-paradigm-design/references/design-principles.md +256 -0
- package/skills/03_Cognitive_Psychology/creativity-self-efficacy-mediation/SKILL.md +270 -0
- package/skills/03_Cognitive_Psychology/creativity-self-efficacy-mediation/references/lavaan-templates.md +172 -0
- package/skills/03_Cognitive_Psychology/divergent-thinking-scoring/SKILL.md +238 -0
- package/skills/03_Cognitive_Psychology/divergent-thinking-scoring/references/scoring-rubric.md +143 -0
- package/skills/03_Cognitive_Psychology/drift-diffusion-model/SKILL.md +203 -0
- package/skills/03_Cognitive_Psychology/drift-diffusion-model/references/fitting-guide.md +571 -0
- package/skills/03_Cognitive_Psychology/drift-diffusion-model/references/model-variants.md +427 -0
- package/skills/03_Cognitive_Psychology/evidence-accumulation-selector/SKILL.md +310 -0
- package/skills/03_Cognitive_Psychology/evidence-accumulation-selector/references/ez-diffusion-formulas.md +137 -0
- package/skills/03_Cognitive_Psychology/signal-detection-analysis/SKILL.md +300 -0
- package/skills/03_Cognitive_Psychology/signal-detection-analysis/references/application-guide.md +278 -0
- package/skills/03_Cognitive_Psychology/signal-detection-analysis/references/sdt-formulas.md +318 -0
- package/skills/03_Cognitive_Psychology/visual-search-array-generator/SKILL.md +283 -0
- package/skills/03_Cognitive_Psychology/visual-search-array-generator/references/array-generation-parameters.yaml +111 -0
- package/skills/04_Psycholinguistics/reading-time-analysis/SKILL.md +301 -0
- package/skills/04_Psycholinguistics/reading-time-analysis/references/measure-computation-guide.md +195 -0
- package/skills/04_Psycholinguistics/self-paced-reading-designer/SKILL.md +257 -0
- package/skills/04_Psycholinguistics/self-paced-reading-designer/references/analysis-guide.md +356 -0
- package/skills/04_Psycholinguistics/self-paced-reading-designer/references/region-segmentation.md +266 -0
- package/skills/04_Psycholinguistics/sentence-stimulus-norming/SKILL.md +346 -0
- package/skills/04_Psycholinguistics/sentence-stimulus-norming/references/lexical-databases-guide.md +184 -0
- package/skills/05_EEG_ERP/eeg-paradigm-designer/SKILL.md +226 -0
- package/skills/05_EEG_ERP/eeg-paradigm-designer/references/component-paradigm-map.md +276 -0
- package/skills/05_EEG_ERP/eeg-paradigm-designer/references/timing-parameters.md +244 -0
- package/skills/05_EEG_ERP/eeg-preprocessing-pipeline-guide/SKILL.md +367 -0
- package/skills/05_EEG_ERP/eeg-preprocessing-pipeline-guide/references/parameter-lookup-tables.md +138 -0
- package/skills/05_EEG_ERP/erp-analysis/SKILL.md +185 -0
- package/skills/05_EEG_ERP/erp-analysis/references/erp-components.md +447 -0
- package/skills/05_EEG_ERP/erp-analysis/references/preprocessing-pipeline.md +277 -0
- package/skills/05_EEG_ERP/erp-analysis/references/statistical-approaches.md +351 -0
- package/skills/05_EEG_ERP/mne-python-guide/SKILL.md +174 -0
- package/skills/05_EEG_ERP/mne-python-guide/references/decoding.md +178 -0
- package/skills/05_EEG_ERP/mne-python-guide/references/io_formats.md +160 -0
- package/skills/05_EEG_ERP/mne-python-guide/references/preprocessing.md +259 -0
- package/skills/05_EEG_ERP/mne-python-guide/references/simulation.md +173 -0
- package/skills/05_EEG_ERP/mne-python-guide/references/source_localization.md +234 -0
- package/skills/05_EEG_ERP/mne-python-guide/references/statistics.md +196 -0
- package/skills/05_EEG_ERP/mne-python-guide/references/time_frequency.md +165 -0
- package/skills/05_EEG_ERP/mne-python-guide/references/visualization.md +175 -0
- package/skills/06_fMRI_Neuroimaging/brain-connectivity-modeler/SKILL.md +317 -0
- package/skills/06_fMRI_Neuroimaging/brain-connectivity-modeler/references/method-implementation-guide.md +116 -0
- package/skills/06_fMRI_Neuroimaging/fmri-glm-analysis-guide/SKILL.md +296 -0
- package/skills/06_fMRI_Neuroimaging/fmri-glm-analysis-guide/references/design-matrix-guide.md +214 -0
- package/skills/06_fMRI_Neuroimaging/fmri-glm-analysis-guide/references/statistical-inference.md +288 -0
- package/skills/06_fMRI_Neuroimaging/fmri-preprocessing-pipeline-guide/SKILL.md +274 -0
- package/skills/06_fMRI_Neuroimaging/fmri-preprocessing-pipeline-guide/references/quality-control.md +336 -0
- package/skills/06_fMRI_Neuroimaging/fmri-preprocessing-pipeline-guide/references/step-by-step-pipeline.md +380 -0
- package/skills/06_fMRI_Neuroimaging/fmri-task-design-guide/SKILL.md +264 -0
- package/skills/06_fMRI_Neuroimaging/fmri-task-design-guide/references/design-optimization-examples.md +114 -0
- package/skills/06_fMRI_Neuroimaging/neural-decoding-analysis/SKILL.md +273 -0
- package/skills/06_fMRI_Neuroimaging/neural-decoding-analysis/references/decoding-methods.md +170 -0
- package/skills/06_fMRI_Neuroimaging/neural-decoding-analysis/references/rsa-guide.md +266 -0
- package/skills/06_fMRI_Neuroimaging/pycortex-guide/SKILL.md +123 -0
- package/skills/06_fMRI_Neuroimaging/pycortex-guide/references/database-subjects.md +179 -0
- package/skills/06_fMRI_Neuroimaging/pycortex-guide/references/dataset-types.md +208 -0
- package/skills/06_fMRI_Neuroimaging/pycortex-guide/references/freesurfer-fmriprep.md +162 -0
- package/skills/06_fMRI_Neuroimaging/pycortex-guide/references/mapping-transforms.md +181 -0
- package/skills/06_fMRI_Neuroimaging/pycortex-guide/references/mni-utils.md +207 -0
- package/skills/06_fMRI_Neuroimaging/pycortex-guide/references/surface-analysis.md +219 -0
- package/skills/06_fMRI_Neuroimaging/pycortex-guide/references/visualization.md +251 -0
- package/skills/07_Computational_Modeling/act-r-model-builder/SKILL.md +297 -0
- package/skills/07_Computational_Modeling/act-r-model-builder/references/model-patterns.md +197 -0
- package/skills/07_Computational_Modeling/act-r-model-builder/references/parameter-table.yaml +204 -0
- package/skills/07_Computational_Modeling/bayesian-cognitive-model-builder/SKILL.md +294 -0
- package/skills/07_Computational_Modeling/bayesian-cognitive-model-builder/references/diagnostics-checklist.md +351 -0
- package/skills/07_Computational_Modeling/bayesian-cognitive-model-builder/references/prior-selection-guide.md +241 -0
- package/skills/07_Computational_Modeling/parameter-recovery-checker/SKILL.md +269 -0
- package/skills/07_Computational_Modeling/parameter-recovery-checker/references/recovery-diagnostics.md +207 -0
- package/skills/08_Computational_Neuroscience/brain-connectivity-modeler/SKILL.md +317 -0
- package/skills/08_Computational_Neuroscience/brain-connectivity-modeler/references/method-implementation-guide.md +116 -0
- package/skills/08_Computational_Neuroscience/neural-decoding-analysis/SKILL.md +273 -0
- package/skills/08_Computational_Neuroscience/neural-decoding-analysis/references/decoding-methods.md +170 -0
- package/skills/08_Computational_Neuroscience/neural-decoding-analysis/references/rsa-guide.md +266 -0
- package/skills/08_Computational_Neuroscience/neural-population-analysis-guide/SKILL.md +305 -0
- package/skills/08_Computational_Neuroscience/neural-population-analysis-guide/references/data-requirements.md +60 -0
- package/skills/08_Computational_Neuroscience/neural-population-analysis-guide/references/method-comparison.md +151 -0
- package/skills/08_Computational_Neuroscience/spiking-network-model-builder/SKILL.md +376 -0
- package/skills/08_Computational_Neuroscience/spiking-network-model-builder/references/hh-parameters.md +117 -0
- package/skills/08_Computational_Neuroscience/spiking-network-model-builder/references/network-regimes.md +130 -0
- package/skills/09_Cellular_Molecular_Neuroscience/calcium-imaging-analysis-guide/SKILL.md +258 -0
- package/skills/09_Cellular_Molecular_Neuroscience/calcium-imaging-analysis-guide/references/indicator-parameters.md +242 -0
- package/skills/09_Cellular_Molecular_Neuroscience/calcium-imaging-analysis-guide/references/pipeline-details.md +211 -0
- package/skills/09_Cellular_Molecular_Neuroscience/optogenetics-protocol-designer/SKILL.md +261 -0
- package/skills/09_Cellular_Molecular_Neuroscience/optogenetics-protocol-designer/references/opsin-catalog.md +124 -0
- package/skills/09_Cellular_Molecular_Neuroscience/optogenetics-protocol-designer/references/stimulation-parameters.md +304 -0
- package/skills/10_Clinical_Neuropsychology/lesion-symptom-mapping-guide/SKILL.md +367 -0
- package/skills/10_Clinical_Neuropsychology/lesion-symptom-mapping-guide/references/disconnection-guide.md +152 -0
- package/skills/10_Clinical_Neuropsychology/lesion-symptom-mapping-guide/references/vlsm-pipeline.md +182 -0
- package/skills/10_Clinical_Neuropsychology/neuropsych-battery-selector/SKILL.md +250 -0
- package/skills/10_Clinical_Neuropsychology/neuropsych-battery-selector/references/deficit-profiles.md +302 -0
- package/skills/10_Clinical_Neuropsychology/neuropsych-battery-selector/references/test-catalog.md +304 -0
- package/skills/11_Developmental_Cognition/infant-looking-time-designer/SKILL.md +345 -0
- package/skills/11_Developmental_Cognition/infant-looking-time-designer/references/age-parameters.yaml +186 -0
- package/skills/12_Social_Cognition/tom-task-selector/SKILL.md +379 -0
- package/skills/12_Social_Cognition/tom-task-selector/references/task-database.md +317 -0
- package/skills/13_Visualization/nature-figure/README.md +442 -0
- package/skills/13_Visualization/nature-figure/SKILL.md +60 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-01-bar-charts.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-02-line-trends.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-03-heatmaps.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-04-scatter-bubble.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-05-radar-polar.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-06-distributions.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-07-forest-interval.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-08-area-stacked.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-09-image-plates.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/chart-atlas/atlas-10-network-matrix.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/assets/Dispersion_motivation.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/assets/Dispersion_observation.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/assets/Dispersion_observation_distillation.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/assets/ImmunoStruct_contrastive.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/assets/ImmunoStruct_results_CEDAR.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/assets/ImmunoStruct_results_IEDB.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/assets/ImmunoStruct_schematic.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/assets/RNAGenScape_schematic.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_CellSpliceNet/figures/ablation.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_CellSpliceNet/figures/comparison.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_CellSpliceNet/plot_ablation.py +86 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_CellSpliceNet/plot_comparison.py +109 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/diffusion_swiss_roll.py +97 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/figures/diffusion_swiss_roll.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/figures/fig2_comparison_GeneRegulatory.pdf +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/figures/fig2_comparison_GeneRegulatory.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/figures/fig2_comparison_Trajectory.pdf +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/figures/fig2_comparison_Trajectory.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/figures/figX_comparison_Ablation.pdf +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/figures/figX_comparison_Ablation.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/plot_comparison_Ablation.py +64 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/plot_comparison_GeneRegulatory.py +74 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Cflows/plot_comparison_Trajectory.py +74 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Dispersion/figures/idea.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Dispersion/figures/illustration.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Dispersion/plot_idea.py +76 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_Dispersion/plot_illustration.py +404 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_FPGM/figures/freq_prior.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_FPGM/plot_freq_prior.py +146 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ImmunoStruct/figures/bars_ablation_Cancer.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ImmunoStruct/figures/bars_ablation_IEDB.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ImmunoStruct/figures/bars_comparison_Cancer.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ImmunoStruct/figures/bars_comparison_IEDB.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ImmunoStruct/plot_bars.py +216 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ImmunoStruct/raw_data.py +125 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/figures/manifold.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/figures/manifold_holes.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/figures/results_comparison_optimization.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/figures/results_comparison_speed.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/figures/results_sweep.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/plot_comparison.py +228 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/plot_hole_manifold.py +82 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/plot_manifold.py +61 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_RNAGenScape/plot_sweep.py +77 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_VIGIL/figures/comparison_posttraining.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_VIGIL/figures/comparison_radar.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_VIGIL/plot_comparison_radar.py +173 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_VIGIL/plot_posttraining.py +82 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/figures/brute_force.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/figures/correctness_by_category.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/figures/correctness_by_subcategory.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/figures/rewriting.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/figures/selfcorrection_math.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/plot_brute_force.py +248 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/plot_correctness_by_category.py +132 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/plot_correctness_by_subcategory.py +131 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/plot_rewriting.py +105 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_brainteaser/plot_selfcorrection_math.py +99 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ophthal_review/figures/composition_heatmap.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ophthal_review/figures/trend_by_month.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ophthal_review/plot_composition.py +81 -0
- package/skills/13_Visualization/nature-figure/assets/figures4papers/figure_ophthal_review/plot_trend.py +125 -0
- package/skills/13_Visualization/nature-figure/assets/gallery/fig1-material-mechanism-rich.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/gallery/fig2-spatial-imaging-rich.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/gallery/fig3-in-vivo-efficacy-rich.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/gallery/fig4-single-cell-systems-rich.png +0 -0
- package/skills/13_Visualization/nature-figure/assets/gallery/fig5-validation-perturbation-rich.png +0 -0
- package/skills/13_Visualization/nature-figure/evals/evals.json +37 -0
- package/skills/13_Visualization/nature-figure/manifest.yaml +57 -0
- package/skills/13_Visualization/nature-figure/references/api.md +428 -0
- package/skills/13_Visualization/nature-figure/references/backend-selection.md +100 -0
- package/skills/13_Visualization/nature-figure/references/chart-types.md +281 -0
- package/skills/13_Visualization/nature-figure/references/common-patterns.md +350 -0
- package/skills/13_Visualization/nature-figure/references/demos.md +65 -0
- package/skills/13_Visualization/nature-figure/references/design-theory.md +436 -0
- package/skills/13_Visualization/nature-figure/references/figure-contract.md +93 -0
- package/skills/13_Visualization/nature-figure/references/nature-2026-observations.md +112 -0
- package/skills/13_Visualization/nature-figure/references/qa-contract.md +119 -0
- package/skills/13_Visualization/nature-figure/references/r-template-index.md +66 -0
- package/skills/13_Visualization/nature-figure/references/r-workflow.md +161 -0
- package/skills/13_Visualization/nature-figure/references/tutorials.md +251 -0
- package/skills/13_Visualization/nature-figure/static/core/contract.md +29 -0
- package/skills/13_Visualization/nature-figure/static/core/stance.md +37 -0
- package/skills/13_Visualization/nature-figure/static/fragments/backend/python.md +37 -0
- package/skills/13_Visualization/nature-figure/static/fragments/backend/r.md +44 -0
- package/skills/14_Writing/markdown-report-writing/SKILL.md +306 -0
- package/skills/14_Writing/markdown-report-writing/references/compatibility-matrix.md +72 -0
- package/skills/14_Writing/markdown-report-writing/references/templates.md +299 -0
- package/skills/15_Others/neuroimaging-power-guide/SKILL.md +324 -0
- package/skills/15_Others/neuroimaging-power-guide/references/effect-size-lookup-tables.md +102 -0
- package/skills/15_Others/neuroimaging-sample-size-calculator/SKILL.md +330 -0
- package/skills/15_Others/neuroimaging-sample-size-calculator/references/worked-examples.md +220 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import numpy as np
|
|
3
|
+
from matplotlib import pyplot as plt
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from dateutil.relativedelta import relativedelta
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
DATA = {
|
|
9
|
+
'names': ['Methodological Contribution (Text-only)', 'Evaluation / Application (Text-only)',
|
|
10
|
+
'Methodological Contribution (Multimodal)', 'Evaluation / Application (Multimodal)'],
|
|
11
|
+
'pub_by_month': np.array(
|
|
12
|
+
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 2, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2],
|
|
13
|
+
[0, 0, 4, 0, 0, 6, 1, 3, 2, 0, 5, 0, 4, 0, 9, 1, 3, 4, 7, 6, 7, 6, 6, 1, 6, 4, 6, 2, 0, 0, 0, 1, 1],
|
|
14
|
+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0],
|
|
15
|
+
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 2, 1, 0, 2, 3, 0, 1, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0]]
|
|
16
|
+
),
|
|
17
|
+
# NOTE: Use `*` to move the label up in the annotation. Each `*` moves it up a bit.
|
|
18
|
+
'dates_llm': {
|
|
19
|
+
'2022-11': 'ChatGPT\n(GPT-3.5)',
|
|
20
|
+
'2023-02': 'Bard',
|
|
21
|
+
'2023-02': 'LlaMA 1',
|
|
22
|
+
'2023-03': 'GPT-4*',
|
|
23
|
+
'2025-08': 'GPT-5',
|
|
24
|
+
'2023-07': 'LlaMA 2',
|
|
25
|
+
'2024-04': 'LlaMA 3',
|
|
26
|
+
'2025-04': 'LlaMA 4',
|
|
27
|
+
'2023-12': 'Gemini 1.0',
|
|
28
|
+
'2024-02': 'Gemini 1.5',
|
|
29
|
+
'2024-12': 'Gemini 2.0',
|
|
30
|
+
'2025-06': 'Gemini 2.5*',
|
|
31
|
+
},
|
|
32
|
+
'dates_vlm': {
|
|
33
|
+
'2023-02': 'BLIP-2',
|
|
34
|
+
'2023-07': 'LlaVA 1.0',
|
|
35
|
+
'2023-9': 'GPT-4v',
|
|
36
|
+
'2023-10': 'LlaVA 1.5*',
|
|
37
|
+
'2023-12': 'Gemini 1.0',
|
|
38
|
+
'2024-02': 'Gemini 1.5',
|
|
39
|
+
'2024-12': 'Gemini 2.0',
|
|
40
|
+
'2025-06': 'Gemini 2.5',
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
def month_year_list(start_year, start_month, n_months):
|
|
45
|
+
start = datetime(start_year, start_month, 1)
|
|
46
|
+
out = []
|
|
47
|
+
for i in range(n_months):
|
|
48
|
+
d = start + relativedelta(months=i)
|
|
49
|
+
out.append(d.strftime('%Y-%m'))
|
|
50
|
+
return out
|
|
51
|
+
|
|
52
|
+
def mark_events(ax, time_arr, y_curve, events, dy=0.1):
|
|
53
|
+
x_idx = {t: i for i, t in enumerate(time_arr)}
|
|
54
|
+
y0, y1 = ax.get_ylim()
|
|
55
|
+
prev_date = None
|
|
56
|
+
for date, label in events.items():
|
|
57
|
+
if prev_date is None:
|
|
58
|
+
prev_date = date
|
|
59
|
+
if date in x_idx:
|
|
60
|
+
i = x_idx[date]
|
|
61
|
+
x, y = i, y_curve[i]
|
|
62
|
+
ax.annotate(
|
|
63
|
+
label.replace('*', ''),
|
|
64
|
+
xy=(x, y),
|
|
65
|
+
xytext=(x, y + (1 + 0.8 * np.uint8(label.count('*'))) * dy * (y1 - y0)),
|
|
66
|
+
ha='center',
|
|
67
|
+
va='bottom',
|
|
68
|
+
fontsize=11,
|
|
69
|
+
arrowprops=dict(arrowstyle='-|>', lw=1.3, color='black',
|
|
70
|
+
shrinkA=0, shrinkB=0, mutation_scale=15)
|
|
71
|
+
)
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
def plot_curve(fig_name: str):
|
|
75
|
+
plt.rcParams['text.usetex'] = True
|
|
76
|
+
plt.rcParams['font.family'] = 'helvetica'
|
|
77
|
+
plt.rcParams['font.size'] = 15
|
|
78
|
+
plt.rcParams['axes.spines.right'] = False
|
|
79
|
+
plt.rcParams['axes.spines.top'] = False
|
|
80
|
+
plt.rcParams['axes.linewidth'] = 2
|
|
81
|
+
colors = ["#9BC8FA", "#ffa8a6", "#13457E", "#850c0a"]
|
|
82
|
+
|
|
83
|
+
os.makedirs(os.path.dirname(fig_name), exist_ok=True)
|
|
84
|
+
fig = plt.figure(figsize=(14, 8))
|
|
85
|
+
num_months = DATA['pub_by_month'].shape[1]
|
|
86
|
+
|
|
87
|
+
ax = fig.add_subplot(2, 1, 1)
|
|
88
|
+
time_arr = month_year_list(start_year=2022, start_month=11, n_months=num_months)
|
|
89
|
+
ax.fill_between(time_arr, np.zeros_like(DATA['pub_by_month'][1, :]), np.cumsum(DATA['pub_by_month'][1, :]), color=colors[1],
|
|
90
|
+
label=DATA['names'][1])
|
|
91
|
+
ax.fill_between(time_arr, np.zeros_like(DATA['pub_by_month'][0, :]), np.cumsum(DATA['pub_by_month'][0, :]), color=colors[0],
|
|
92
|
+
label=DATA['names'][0])
|
|
93
|
+
ax.plot(time_arr, np.cumsum(DATA['pub_by_month'][0, :]), lw=3, c=colors[2])
|
|
94
|
+
ax.plot(time_arr, np.cumsum(DATA['pub_by_month'][1, :]), lw=3, c=colors[3])
|
|
95
|
+
mark_events(ax, time_arr, np.cumsum(DATA['pub_by_month'][1, :]), DATA['dates_llm'])
|
|
96
|
+
ax.legend(frameon=False)
|
|
97
|
+
ax.set_xticks(time_arr[2::6])
|
|
98
|
+
ax.set_ylim([0, 105])
|
|
99
|
+
ax.set_ylabel('Cumulative\nPublication Count\n(Text-only)')
|
|
100
|
+
|
|
101
|
+
ax = fig.add_subplot(2, 1, 2)
|
|
102
|
+
time_arr = month_year_list(start_year=2022, start_month=11, n_months=num_months)
|
|
103
|
+
ax.fill_between(time_arr, np.zeros_like(DATA['pub_by_month'][3, :]), np.cumsum(DATA['pub_by_month'][3, :]), color=colors[1],
|
|
104
|
+
hatch='\\\\\\', edgecolor='black', label=DATA['names'][3])
|
|
105
|
+
ax.fill_between(time_arr, np.zeros_like(DATA['pub_by_month'][3, :]), np.cumsum(DATA['pub_by_month'][3, :]), color=colors[1],
|
|
106
|
+
facecolor='none', edgecolor='white', linewidth=2) # To visually "erase" the border.
|
|
107
|
+
ax.fill_between(time_arr, np.zeros_like(DATA['pub_by_month'][2, :]), np.cumsum(DATA['pub_by_month'][2, :]), color=colors[0],
|
|
108
|
+
hatch='///', edgecolor='black', label=DATA['names'][2])
|
|
109
|
+
ax.fill_between(time_arr, np.zeros_like(DATA['pub_by_month'][2, :]), np.cumsum(DATA['pub_by_month'][2, :]), color=colors[0],
|
|
110
|
+
facecolor='none', edgecolor='white', linewidth=2) # To visually "erase" the border.
|
|
111
|
+
ax.plot(time_arr, np.cumsum(DATA['pub_by_month'][2, :]), lw=3, c=colors[2])
|
|
112
|
+
ax.plot(time_arr, np.cumsum(DATA['pub_by_month'][3, :]), lw=3, c=colors[3])
|
|
113
|
+
ax.legend(frameon=False)
|
|
114
|
+
mark_events(ax, time_arr, np.cumsum(DATA['pub_by_month'][3, :]), DATA['dates_vlm'])
|
|
115
|
+
ax.set_xticks(time_arr[2::6])
|
|
116
|
+
ax.set_ylim([0, 24])
|
|
117
|
+
ax.set_ylabel('Cumulative\nPublication Count\n(Multimodal)')
|
|
118
|
+
|
|
119
|
+
fig.tight_layout(pad=2)
|
|
120
|
+
fig.savefig(fig_name, dpi=300)
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
if __name__ == '__main__':
|
|
125
|
+
plot_curve('./figures/trend_by_month.png')
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/skills/13_Visualization/nature-figure/assets/gallery/fig4-single-cell-systems-rich.png
ADDED
|
Binary file
|
package/skills/13_Visualization/nature-figure/assets/gallery/fig5-validation-perturbation-rich.png
ADDED
|
Binary file
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "nature-figure",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": "backend-exclusivity-r-missing-runtime",
|
|
6
|
+
"prompt": "Use R to remake the provided ecological heatmap plus taxonomy-flow figure in Nature style with simulated data. Assume R/Rscript is not installed locally.",
|
|
7
|
+
"expected_output": "The assistant must not use Python or any non-R plotting backend to draw a preview or export. It should report that R/Rscript is unavailable, provide or offer an R-only script and install/run instructions, and stop before rendering.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
{
|
|
10
|
+
"name": "no_cross_backend_rendering",
|
|
11
|
+
"description": "When R is selected and unavailable, no Python/matplotlib/seaborn/plotly preview, SVG, PDF, TIFF, or PNG is generated as a substitute."
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "selected_backend_blocker_reported",
|
|
15
|
+
"description": "The response clearly reports the missing R runtime or package blocker and does not present a non-R figure as completed output."
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"files": []
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "backend-exclusivity-python-missing-package",
|
|
22
|
+
"prompt": "Use Python to make a Nature-style multi-panel heatmap and flow figure with simulated data. Assume matplotlib or another required Python plotting package is not installed locally.",
|
|
23
|
+
"expected_output": "The assistant must not use R or any non-Python plotting backend to draw a preview or export. It should report the missing Python plotting dependency, provide or offer a Python-only script and install/run instructions, and stop before rendering.",
|
|
24
|
+
"assertions": [
|
|
25
|
+
{
|
|
26
|
+
"name": "no_cross_backend_rendering",
|
|
27
|
+
"description": "When Python is selected and unavailable, no R/ggplot2/ComplexHeatmap/patchwork preview, SVG, PDF, TIFF, or PNG is generated as a substitute."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "selected_backend_blocker_reported",
|
|
31
|
+
"description": "The response clearly reports the missing Python runtime or package blocker and does not present a non-Python figure as completed output."
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"files": []
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: nature-figure
|
|
2
|
+
version: 2.0.0
|
|
3
|
+
description: >
|
|
4
|
+
Declarative manifest for the static/dynamic split. SKILL.md uses this to
|
|
5
|
+
decide which fragments to load for a given figure request. The main axis is
|
|
6
|
+
the plotting backend (Python or R), which is a blocking gate: it must be
|
|
7
|
+
chosen explicitly before any figure is drawn. The large body of design,
|
|
8
|
+
API, pattern, and QA material stays in on-demand references.
|
|
9
|
+
|
|
10
|
+
always_load:
|
|
11
|
+
# Skill-local core (figure does not use the prose-oriented _shared layer)
|
|
12
|
+
- static/core/contract.md
|
|
13
|
+
- static/core/stance.md
|
|
14
|
+
|
|
15
|
+
axes:
|
|
16
|
+
backend:
|
|
17
|
+
detect: |
|
|
18
|
+
BLOCKING GATE. Determine the plotting backend from an explicit user
|
|
19
|
+
choice or a clearly language-specific input file/workflow. If the user
|
|
20
|
+
has NOT explicitly chosen Python or R, ask exactly one concise question —
|
|
21
|
+
"Python or R?" — and stop. Do not default, do not guess, do not generate
|
|
22
|
+
mock data or scripts before the answer. Only recommend a backend when the
|
|
23
|
+
user explicitly asks you to choose; in that case use
|
|
24
|
+
references/backend-selection.md, state the reason, then proceed.
|
|
25
|
+
Once selected, the backend is exclusive for all drawing, previewing,
|
|
26
|
+
exporting, and visual QA.
|
|
27
|
+
values:
|
|
28
|
+
python: static/fragments/backend/python.md
|
|
29
|
+
r: static/fragments/backend/r.md
|
|
30
|
+
multi: false
|
|
31
|
+
|
|
32
|
+
references:
|
|
33
|
+
on_demand:
|
|
34
|
+
- condition: convert a user request into core conclusion, evidence hierarchy, panel map, and review-risk checks
|
|
35
|
+
path: references/figure-contract.md
|
|
36
|
+
- condition: user has not chosen Python/R, asks for a recommendation, or a mixed Python/R workflow is possible
|
|
37
|
+
path: references/backend-selection.md
|
|
38
|
+
- condition: user chooses R or provides R scripts/templates/data
|
|
39
|
+
path: references/r-workflow.md
|
|
40
|
+
- condition: adapt a user-provided or private R template collection without exposing source paths
|
|
41
|
+
path: references/r-template-index.md
|
|
42
|
+
- condition: before final delivery, revision package, microscopy/blot figure, or journal-specific audit
|
|
43
|
+
path: references/qa-contract.md
|
|
44
|
+
- condition: typography, color theory, layout rationale, export policy
|
|
45
|
+
path: references/design-theory.md
|
|
46
|
+
- condition: Python PALETTE, helper function signatures, validation rules
|
|
47
|
+
path: references/api.md
|
|
48
|
+
- condition: "Python layout patterns: hero panels, legend-only axes, dark image plates, asymmetric layouts"
|
|
49
|
+
path: references/common-patterns.md
|
|
50
|
+
- condition: "real Nature page archetypes: schematic-led composites, dark image plates, clinical triptychs, asymmetric hero layouts"
|
|
51
|
+
path: references/nature-2026-observations.md
|
|
52
|
+
- condition: "end-to-end walkthroughs: bars, trends, heatmaps"
|
|
53
|
+
path: references/tutorials.md
|
|
54
|
+
- condition: "radar, 3D sphere, fill_between, scatter patterns"
|
|
55
|
+
path: references/chart-types.md
|
|
56
|
+
- condition: bundled figures4papers Python scripts and output previews for concrete pattern adaptation
|
|
57
|
+
path: references/demos.md
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
# API Reference — Nature Figure Making
|
|
2
|
+
|
|
3
|
+
Conventions, constants, and reusable code blocks. Implement in your script or adapt as needed.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Constants
|
|
8
|
+
|
|
9
|
+
### PALETTE
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
PALETTE = {
|
|
13
|
+
"blue_main": "#0F4D92",
|
|
14
|
+
"blue_secondary": "#3775BA",
|
|
15
|
+
"green_1": "#DDF3DE",
|
|
16
|
+
"green_2": "#AADCA9",
|
|
17
|
+
"green_3": "#8BCF8B",
|
|
18
|
+
"red_1": "#F6CFCB",
|
|
19
|
+
"red_2": "#E9A6A1",
|
|
20
|
+
"red_strong": "#B64342",
|
|
21
|
+
"neutral_light": "#CFCECE",
|
|
22
|
+
"neutral_mid": "#767676",
|
|
23
|
+
"neutral_dark": "#4D4D4D",
|
|
24
|
+
"neutral_black": "#272727",
|
|
25
|
+
"gold": "#FFD700",
|
|
26
|
+
"teal": "#42949E",
|
|
27
|
+
"violet": "#9A4D8E",
|
|
28
|
+
"magenta":"#EA84DD",
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
DEFAULT_COLORS = [
|
|
32
|
+
PALETTE["blue_main"],
|
|
33
|
+
PALETTE["green_3"],
|
|
34
|
+
PALETTE["red_strong"],
|
|
35
|
+
PALETTE["teal"],
|
|
36
|
+
PALETTE["violet"],
|
|
37
|
+
PALETTE["neutral_light"],
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
PALETTE_NMI_PASTEL = {
|
|
41
|
+
"baseline_dark": "#484878",
|
|
42
|
+
"baseline_mid": "#7884B4",
|
|
43
|
+
"baseline_soft": "#B4C0E4",
|
|
44
|
+
"ours_tiny": "#E4E4F0",
|
|
45
|
+
"ours_base": "#E4CCD8",
|
|
46
|
+
"ours_large": "#F0C0CC",
|
|
47
|
+
"bg_lilac": "#E0E0F0",
|
|
48
|
+
"bg_aqua": "#E0F0F0",
|
|
49
|
+
"bg_peach": "#F0E0D0",
|
|
50
|
+
"neutral_light": "#D8D8D8",
|
|
51
|
+
"neutral_mid": "#A8A8A8",
|
|
52
|
+
"neutral_dark": "#606060",
|
|
53
|
+
"delta_up": "#2E9E44",
|
|
54
|
+
"delta_down": "#E53935",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
DEFAULT_COLORS_NMI_PASTEL = [
|
|
58
|
+
PALETTE_NMI_PASTEL["baseline_dark"],
|
|
59
|
+
PALETTE_NMI_PASTEL["baseline_mid"],
|
|
60
|
+
PALETTE_NMI_PASTEL["baseline_soft"],
|
|
61
|
+
PALETTE_NMI_PASTEL["ours_tiny"],
|
|
62
|
+
PALETTE_NMI_PASTEL["ours_base"],
|
|
63
|
+
PALETTE_NMI_PASTEL["ours_large"],
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
PALETTE_NATURE_IMAGING = {
|
|
67
|
+
"bg": "#000000",
|
|
68
|
+
"context": "#B8B8B8",
|
|
69
|
+
"cyan": "#22D7E6",
|
|
70
|
+
"magenta": "#FF2AD4",
|
|
71
|
+
"white": "#FFFFFF",
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
PALETTE_NATURE_MATERIAL = {
|
|
75
|
+
"aqua": "#77D7D1",
|
|
76
|
+
"teal": "#33B5A5",
|
|
77
|
+
"lilac": "#B9A7E8",
|
|
78
|
+
"violet": "#7C6CCF",
|
|
79
|
+
"callout_red": "#E53935",
|
|
80
|
+
"neutral": "#D9D9D9",
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
PALETTE_NATURE_CLINICAL = {
|
|
84
|
+
"baseline": "#272727",
|
|
85
|
+
"week6": "#E28E2C",
|
|
86
|
+
"week13": "#D24B40",
|
|
87
|
+
"week26": "#5B8FD6",
|
|
88
|
+
"year1": "#7BAA5B",
|
|
89
|
+
"year2": "#C45AD6",
|
|
90
|
+
"group_band": "#F2E6D9",
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
PALETTE_NATURE_GENOMICS = {
|
|
94
|
+
"neutral_light": "#D8D8D8",
|
|
95
|
+
"neutral_mid": "#8F8F8F",
|
|
96
|
+
"wave1": "#D9544D",
|
|
97
|
+
"wave2": "#5B7FCA",
|
|
98
|
+
"wave3": "#B89BD9",
|
|
99
|
+
"outline": "#4D4D4D",
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Use `DEFAULT_COLORS` when color itself carries explicit semantic meaning (`hero`, `baseline`, `positive variant`).
|
|
104
|
+
Use `DEFAULT_COLORS_NMI_PASTEL` when several compared methods belong to one or two related families and the page
|
|
105
|
+
should feel visually unified.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## MANDATORY font + SVG rules (always first, no exceptions)
|
|
110
|
+
|
|
111
|
+
These three lines are **non-negotiable** and must appear at the top of every script,
|
|
112
|
+
before any figure is created. They guarantee editable text in SVG output:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
plt.rcParams['font.family'] = 'sans-serif'
|
|
116
|
+
plt.rcParams['font.sans-serif'] = ['Arial', 'DejaVu Sans', 'Liberation Sans']
|
|
117
|
+
plt.rcParams['svg.fonttype'] = 'none' # keeps text as <text> nodes, not paths
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Why `svg.fonttype = 'none'`**: matplotlib's default (`'path'`) converts every
|
|
121
|
+
glyph to a bezier path, making text unselectable, unsearchable, and impossible to
|
|
122
|
+
re-align in Illustrator / Inkscape. With `'none'`, text stays as SVG `<text>` elements
|
|
123
|
+
and font substitution happens at render time.
|
|
124
|
+
|
|
125
|
+
**Output format**: always save as `.svg` (primary). PNG/PDF are optional secondary
|
|
126
|
+
exports. Never use `.png` alone when the figure contains text that may need adjustment.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## apply_publication_style()
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
def apply_publication_style(font_size=16, axes_linewidth=2.5, use_tex=False):
|
|
134
|
+
"""Apply Nature-style rcParams. Call once before creating any figures."""
|
|
135
|
+
# ── MANDATORY: editable SVG text ──────────────────────────────────────────
|
|
136
|
+
plt.rcParams['font.family'] = 'sans-serif'
|
|
137
|
+
plt.rcParams['font.sans-serif'] = ['Arial', 'DejaVu Sans', 'Liberation Sans']
|
|
138
|
+
plt.rcParams['svg.fonttype'] = 'none'
|
|
139
|
+
# ── Layout & style ────────────────────────────────────────────────────────
|
|
140
|
+
plt.rcParams['font.size'] = font_size
|
|
141
|
+
plt.rcParams['axes.spines.right'] = False
|
|
142
|
+
plt.rcParams['axes.spines.top'] = False
|
|
143
|
+
plt.rcParams['axes.linewidth'] = axes_linewidth
|
|
144
|
+
plt.rcParams['legend.frameon'] = False
|
|
145
|
+
if use_tex:
|
|
146
|
+
plt.rcParams['text.usetex'] = True
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Presets:**
|
|
150
|
+
- Large bar panels: `apply_publication_style(font_size=24, axes_linewidth=3)`
|
|
151
|
+
- Compact figures: `apply_publication_style(font_size=15, axes_linewidth=2)`
|
|
152
|
+
- Dense journal-width multi-panels: `apply_publication_style(font_size=8, axes_linewidth=1)`
|
|
153
|
+
- LaTeX labels: `apply_publication_style(use_tex=True)`
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## is_dark(hex_color, threshold=128)
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
def is_dark(hex_color, threshold=128):
|
|
161
|
+
"""Return True if hex color is dark (use white text on it)."""
|
|
162
|
+
c = hex_color.lstrip('#')
|
|
163
|
+
r, g, b = int(c[0:2], 16), int(c[2:4], 16), int(c[4:6], 16)
|
|
164
|
+
return (0.299*r + 0.587*g + 0.114*b) < threshold
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## add_panel_label(ax, label, ...)
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
def add_panel_label(ax, label, x=-0.06, y=1.02, fontsize=14,
|
|
173
|
+
color='black', fontweight='bold'):
|
|
174
|
+
"""Place a Nature-style panel label near the top-left edge."""
|
|
175
|
+
ax.text(
|
|
176
|
+
x, y, label,
|
|
177
|
+
transform=ax.transAxes,
|
|
178
|
+
fontsize=fontsize,
|
|
179
|
+
fontweight=fontweight,
|
|
180
|
+
color=color,
|
|
181
|
+
ha='left',
|
|
182
|
+
va='bottom',
|
|
183
|
+
)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
For dark image plates, move the label inside the panel and switch to white:
|
|
187
|
+
`add_panel_label(ax, 'a', x=0.01, y=0.98, color='white')`
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## style_dark_image_ax(ax, ...)
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
def style_dark_image_ax(ax, facecolor='black'):
|
|
195
|
+
"""Prepare an axes for microscopy / rendering plates."""
|
|
196
|
+
ax.set_facecolor(facecolor)
|
|
197
|
+
ax.set_xticks([])
|
|
198
|
+
ax.set_yticks([])
|
|
199
|
+
for spine in ax.spines.values():
|
|
200
|
+
spine.set_visible(False)
|
|
201
|
+
return ax
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## make_grouped_bar(ax, categories, series, labels, ...)
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
def make_grouped_bar(ax, categories, series, labels,
|
|
210
|
+
ylabel='Value', colors=None,
|
|
211
|
+
annotate=False, bar_width=0.8,
|
|
212
|
+
error_kw=None):
|
|
213
|
+
"""
|
|
214
|
+
Grouped bar chart.
|
|
215
|
+
|
|
216
|
+
Parameters
|
|
217
|
+
----------
|
|
218
|
+
ax : matplotlib Axes
|
|
219
|
+
categories : list[str] — x-axis category names (length K)
|
|
220
|
+
series : list[array] — one array per group (each length K)
|
|
221
|
+
labels : list[str] — legend label per group
|
|
222
|
+
ylabel : str
|
|
223
|
+
colors : list[str] | None — defaults to DEFAULT_COLORS; override with
|
|
224
|
+
DEFAULT_COLORS_NMI_PASTEL for unified-family figures
|
|
225
|
+
annotate : bool — print value above each bar
|
|
226
|
+
bar_width : float — total width for all bars in one category
|
|
227
|
+
error_kw : dict — passed to ax.bar as error_kw
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
list[BarContainer]
|
|
232
|
+
"""
|
|
233
|
+
import numpy as np
|
|
234
|
+
if colors is None:
|
|
235
|
+
colors = DEFAULT_COLORS
|
|
236
|
+
if error_kw is None:
|
|
237
|
+
error_kw = {'elinewidth': 2, 'capthick': 2, 'capsize': 10}
|
|
238
|
+
n_groups = len(series)
|
|
239
|
+
n_cats = len(categories)
|
|
240
|
+
w = bar_width / n_groups
|
|
241
|
+
x = np.arange(n_cats)
|
|
242
|
+
containers = []
|
|
243
|
+
for i, (vals, label, color) in enumerate(zip(series, labels, colors)):
|
|
244
|
+
offset = (i - (n_groups - 1) / 2) * w
|
|
245
|
+
bars = ax.bar(x + offset, vals, width=w, label=label,
|
|
246
|
+
color=color, edgecolor='black', linewidth=1.5,
|
|
247
|
+
error_kw=error_kw)
|
|
248
|
+
containers.append(bars)
|
|
249
|
+
if annotate:
|
|
250
|
+
for bar, val in zip(bars, vals):
|
|
251
|
+
ax.text(bar.get_x() + bar.get_width() / 2,
|
|
252
|
+
bar.get_height() + 0.01,
|
|
253
|
+
f'{val:.2f}', ha='center', va='bottom', fontsize=10)
|
|
254
|
+
ax.set_xticks(x)
|
|
255
|
+
ax.set_xticklabels(categories)
|
|
256
|
+
ax.set_ylabel(ylabel)
|
|
257
|
+
ax.legend()
|
|
258
|
+
return containers
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## make_trend(ax, x, y_series, labels, ...)
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
def make_trend(ax, x, y_series, labels,
|
|
267
|
+
colors=None, ylabel=None, xlabel=None,
|
|
268
|
+
show_shadow=False, shadow_alpha=0.15,
|
|
269
|
+
lw=2.5, marker='o', markersize=8):
|
|
270
|
+
"""
|
|
271
|
+
Multi-line trend plot.
|
|
272
|
+
|
|
273
|
+
Parameters
|
|
274
|
+
----------
|
|
275
|
+
x : array-like — shared x values
|
|
276
|
+
y_series : list[array] — one 1D array per line
|
|
277
|
+
labels : list[str]
|
|
278
|
+
show_shadow : bool — fill_between ± std if y_series contains 2D arrays (rows=runs)
|
|
279
|
+
"""
|
|
280
|
+
import numpy as np
|
|
281
|
+
if colors is None:
|
|
282
|
+
colors = DEFAULT_COLORS
|
|
283
|
+
for y, label, color in zip(y_series, labels, colors):
|
|
284
|
+
y = np.asarray(y)
|
|
285
|
+
if y.ndim == 2:
|
|
286
|
+
mean, std = y.mean(0), y.std(0)
|
|
287
|
+
else:
|
|
288
|
+
mean, std = y, None
|
|
289
|
+
ax.plot(x, mean, color=color, lw=lw, marker=marker,
|
|
290
|
+
markersize=markersize, label=label)
|
|
291
|
+
if show_shadow and std is not None:
|
|
292
|
+
ax.fill_between(x, mean - std, mean + std,
|
|
293
|
+
color=color, alpha=shadow_alpha)
|
|
294
|
+
if ylabel:
|
|
295
|
+
ax.set_ylabel(ylabel)
|
|
296
|
+
if xlabel:
|
|
297
|
+
ax.set_xlabel(xlabel)
|
|
298
|
+
ax.legend()
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## make_forest_plot(ax, labels, estimates, ci_low, ci_high, ...)
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
def make_forest_plot(ax, labels, estimates, ci_low, ci_high,
|
|
307
|
+
colors=None, ref=0.0, xlabel=None, xlim=None,
|
|
308
|
+
marker='o', markersize=5, lw=1.5):
|
|
309
|
+
"""
|
|
310
|
+
Minimal forest plot helper for Nature-style clinical/statistical panels.
|
|
311
|
+
"""
|
|
312
|
+
import numpy as np
|
|
313
|
+
y = np.arange(len(labels))[::-1]
|
|
314
|
+
if colors is None:
|
|
315
|
+
colors = ['#B64342'] * len(labels)
|
|
316
|
+
for yi, est, lo, hi, color in zip(y, estimates, ci_low, ci_high, colors):
|
|
317
|
+
ax.plot([lo, hi], [yi, yi], color=color, lw=lw)
|
|
318
|
+
ax.plot(est, yi, marker=marker, ms=markersize, color=color)
|
|
319
|
+
ax.axvline(ref, color='#767676', linestyle='--', linewidth=1.2, alpha=0.8)
|
|
320
|
+
ax.set_yticks(y)
|
|
321
|
+
ax.set_yticklabels(labels)
|
|
322
|
+
if xlabel:
|
|
323
|
+
ax.set_xlabel(xlabel)
|
|
324
|
+
if xlim is not None:
|
|
325
|
+
ax.set_xlim(xlim)
|
|
326
|
+
ax.spines['right'].set_visible(False)
|
|
327
|
+
ax.spines['top'].set_visible(False)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Use pale `ax.axhspan(...)` bands behind contiguous label groups when you need the
|
|
331
|
+
clinical-triptych look from `Nature`.
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## make_heatmap(ax, matrix, ...)
|
|
336
|
+
|
|
337
|
+
```python
|
|
338
|
+
def make_heatmap(ax, matrix, x_labels=None, y_labels=None,
|
|
339
|
+
cmap='magma', cbar_label=None, annotate=False,
|
|
340
|
+
fmt='{:.2f}', fontsize=12):
|
|
341
|
+
"""
|
|
342
|
+
2D heatmap with optional colorbar and cell annotations.
|
|
343
|
+
"""
|
|
344
|
+
import numpy as np
|
|
345
|
+
import matplotlib as mpl
|
|
346
|
+
im = ax.imshow(matrix, cmap=cmap, aspect='auto')
|
|
347
|
+
if cbar_label:
|
|
348
|
+
cbar = ax.figure.colorbar(im, ax=ax)
|
|
349
|
+
cbar.set_label(cbar_label)
|
|
350
|
+
if x_labels:
|
|
351
|
+
ax.set_xticks(range(len(x_labels)))
|
|
352
|
+
ax.set_xticklabels(x_labels, rotation=30, ha='right')
|
|
353
|
+
if y_labels:
|
|
354
|
+
ax.set_yticks(range(len(y_labels)))
|
|
355
|
+
ax.set_yticklabels(y_labels)
|
|
356
|
+
if annotate:
|
|
357
|
+
norm = mpl.colors.Normalize(vmin=matrix.min(), vmax=matrix.max())
|
|
358
|
+
cm_obj = plt.get_cmap(cmap)
|
|
359
|
+
for (i, j), val in np.ndenumerate(matrix):
|
|
360
|
+
r, g, b, _ = cm_obj(norm(val))
|
|
361
|
+
lum = 0.299*r + 0.587*g + 0.114*b
|
|
362
|
+
color = 'white' if lum < 0.5 else 'black'
|
|
363
|
+
ax.text(j, i, fmt.format(val), ha='center', va='center',
|
|
364
|
+
fontsize=fontsize, color=color)
|
|
365
|
+
ax.set_frame_on(False)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## finalize_figure(fig, out_path, ...)
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
def finalize_figure(fig, out_path, formats=None, dpi=300,
|
|
374
|
+
pad=2, bbox_inches=None, close=True):
|
|
375
|
+
"""
|
|
376
|
+
Apply tight_layout and save figure.
|
|
377
|
+
|
|
378
|
+
Parameters
|
|
379
|
+
----------
|
|
380
|
+
out_path : str — path without extension, or with extension
|
|
381
|
+
formats : list — e.g. ['png', 'pdf']. If None, uses extension of out_path.
|
|
382
|
+
dpi : int — 300 standard, 600 for dense bar panels
|
|
383
|
+
pad : float — tight_layout pad (2 default, 1 for compact multi-panel)
|
|
384
|
+
"""
|
|
385
|
+
import os
|
|
386
|
+
from pathlib import Path
|
|
387
|
+
fig.tight_layout(pad=pad)
|
|
388
|
+
base = Path(out_path)
|
|
389
|
+
os.makedirs(base.parent, exist_ok=True)
|
|
390
|
+
if formats is None:
|
|
391
|
+
formats = [base.suffix.lstrip('.') or 'png']
|
|
392
|
+
base = base.with_suffix('')
|
|
393
|
+
saved = []
|
|
394
|
+
for fmt in formats:
|
|
395
|
+
p = str(base) + f'.{fmt}'
|
|
396
|
+
kw = {}
|
|
397
|
+
if bbox_inches is not None:
|
|
398
|
+
kw['bbox_inches'] = bbox_inches
|
|
399
|
+
fig.savefig(p, dpi=dpi, **kw)
|
|
400
|
+
saved.append(p)
|
|
401
|
+
if close:
|
|
402
|
+
plt.close(fig)
|
|
403
|
+
return saved
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Validation Rules
|
|
409
|
+
|
|
410
|
+
- `make_grouped_bar`: `len(categories)` must equal length of each array in `series`.
|
|
411
|
+
- `make_trend`: each array in `y_series` must have same length as `x`.
|
|
412
|
+
- `make_heatmap`: `matrix` must be 2D; `x_labels` length = `matrix.shape[1]`; `y_labels` length = `matrix.shape[0]`.
|
|
413
|
+
- `finalize_figure`: supported formats — `png`, `pdf`, `svg`, `eps`, `jpg`, `tif`.
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## Conventions
|
|
418
|
+
|
|
419
|
+
- Save outputs under `./figures/` (or path given by user); `finalize_figure` creates parent dirs.
|
|
420
|
+
- In headless / batch runs, set non-interactive backend before importing pyplot:
|
|
421
|
+
```python
|
|
422
|
+
import matplotlib
|
|
423
|
+
matplotlib.use('Agg')
|
|
424
|
+
import matplotlib.pyplot as plt
|
|
425
|
+
```
|
|
426
|
+
- Always `plt.close(fig)` after saving to free memory.
|
|
427
|
+
- For multi-panel figures, prefer one baseline family plus one hero family; reserve green/red for delta cues.
|
|
428
|
+
- When color roles, resolution, or layout are underspecified and would change the figure, confirm with user before finalizing.
|