@brainpilot/skills 0.0.6 → 0.0.7
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/package.json +2 -2
- package/skills/01_Meta-Skills/academic-research-hub/SKILL.md +108 -0
- package/skills/01_Meta-Skills/academic-research-hub/scripts/requirements.txt +17 -0
- package/skills/01_Meta-Skills/academic-research-hub/scripts/research.py +781 -0
- package/skills/01_Meta-Skills/beautiful-log/SKILL.md +64 -0
- package/skills/01_Meta-Skills/beautiful-log/scripts/beautiful_log.py +274 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/SKILL.md +130 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/assets/config.template.yaml +54 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/assets/top5_digest_template.md +5 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/build_top5_digest.py +300 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/common.py +137 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/merge_results.py +106 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/run_pipeline.py +177 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/search_arxiv.py +162 -0
- package/skills/01_Meta-Skills/ethoclaw-daily-paper/scripts/search_pubmed.py +202 -0
- package/skills/01_Meta-Skills/ethoclaw-normalize-tabular/SKILL.md +173 -0
- package/skills/01_Meta-Skills/ethoclaw-normalize-tabular/scripts/normalize_data.py +874 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/SKILL.md +134 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/references/confirmation-prompts.md +31 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/references/output-patterns.md +45 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_markdown_deliverables.py +41 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_research_log.py +84 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/build_summary_md.py +63 -0
- package/skills/01_Meta-Skills/ethoclaw-pdf-research/scripts/extract_pdf_bundle.py +140 -0
- package/skills/01_Meta-Skills/experiment-controller/SKILL.md +140 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/SKILL.md +366 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/entity_resolution.py +120 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/extraction_prompt_template.txt +19 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/graph_query.py +106 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/hypothesis_cli_reference.py +42 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/new_data_source_template.py +116 -0
- package/skills/01_Meta-Skills/knowledge-graph-builder/scripts/requirements.txt +15 -0
- package/skills/01_Meta-Skills/method-design/SKILL.md +61 -0
- package/skills/01_Meta-Skills/multi-search-engine/SKILL.md +119 -0
- package/skills/01_Meta-Skills/research-idea/SKILL.md +65 -0
- package/skills/05_EEG_ERP/eeg-skill/SKILL.md +197 -0
- package/skills/05_EEG_ERP/meg-skill/SKILL.md +188 -0
- package/skills/05_EEG_ERP/meg-skill/scripts/time_frequency.py +223 -0
- package/skills/05_EEG_ERP/mne-eeg-tool/SKILL.md +165 -0
- package/skills/05_EEG_ERP/mne-eeg-tool/scripts/eeg_pipeline_reference.py +231 -0
- package/skills/05_EEG_ERP/seed-iv-skill/SKILL.md +184 -0
- package/skills/05_EEG_ERP/seed-iv-skill/scripts/classify_seed_iv.py +154 -0
- package/skills/05_EEG_ERP/seed-iv-skill/scripts/extract_seed_iv_features.py +190 -0
- package/skills/05_EEG_ERP/seed-iv-skill/scripts/validate_seed_iv.py +102 -0
- package/skills/05_EEG_ERP/seed-vig-skill/SKILL.md +182 -0
- package/skills/05_EEG_ERP/seed-vig-skill/scripts/classify_seed_vig.py +165 -0
- package/skills/05_EEG_ERP/seed-vig-skill/scripts/extract_seed_vig_features.py +185 -0
- package/skills/05_EEG_ERP/seed-vig-skill/scripts/validate_seed_vig.py +88 -0
- package/skills/06_fMRI_Neuroimaging/abcd-skill/SKILL.md +308 -0
- package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/abcd_qc_summary.py +449 -0
- package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/extract_abcd_phenotype.py +292 -0
- package/skills/06_fMRI_Neuroimaging/abcd-skill/scripts/reorganize_abcd.py +387 -0
- package/skills/06_fMRI_Neuroimaging/abide-skill/SKILL.md +302 -0
- package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/abide_qc_summary.py +317 -0
- package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/extract_abide_phenotype.py +267 -0
- package/skills/06_fMRI_Neuroimaging/abide-skill/scripts/reorganize_abide.py +387 -0
- package/skills/06_fMRI_Neuroimaging/adhd200-skill/SKILL.md +244 -0
- package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/adhd200_qc_summary.py +98 -0
- package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/extract_adhd200_phenotype.py +134 -0
- package/skills/06_fMRI_Neuroimaging/adhd200-skill/scripts/reorganize_adhd200.py +206 -0
- package/skills/06_fMRI_Neuroimaging/adni-skill/SKILL.md +358 -0
- package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/generate_adni_task_files.py +1305 -0
- package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/generate_vqa_from_tasks.py +766 -0
- package/skills/06_fMRI_Neuroimaging/adni-skill/scripts/reorganize_adni.py +491 -0
- package/skills/06_fMRI_Neuroimaging/aibl-skill/SKILL.md +295 -0
- package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/aibl_qc_summary.py +260 -0
- package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/extract_aibl_phenotype.py +365 -0
- package/skills/06_fMRI_Neuroimaging/aibl-skill/scripts/reorganize_aibl.py +394 -0
- package/skills/06_fMRI_Neuroimaging/aomic-skill/SKILL.md +292 -0
- package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/aomic_qc_summary.py +258 -0
- package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/extract_aomic_phenotype.py +284 -0
- package/skills/06_fMRI_Neuroimaging/aomic-skill/scripts/reorganize_aomic.py +322 -0
- package/skills/06_fMRI_Neuroimaging/asl-skill/SKILL.md +168 -0
- package/skills/06_fMRI_Neuroimaging/asl-skill/scripts/compute_cbf.py +224 -0
- package/skills/06_fMRI_Neuroimaging/bids-organizer/SKILL.md +241 -0
- package/skills/06_fMRI_Neuroimaging/bold5000-skill/SKILL.md +186 -0
- package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/bold5000_qc_summary.py +96 -0
- package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/extract_bold5000_stimulus.py +125 -0
- package/skills/06_fMRI_Neuroimaging/bold5000-skill/scripts/reorganize_bold5000.py +102 -0
- package/skills/06_fMRI_Neuroimaging/camcan-skill/SKILL.md +213 -0
- package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/camcan_qc_summary.py +131 -0
- package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/extract_camcan_phenotype.py +145 -0
- package/skills/06_fMRI_Neuroimaging/camcan-skill/scripts/validate_camcan.py +141 -0
- package/skills/06_fMRI_Neuroimaging/cobre-skill/SKILL.md +201 -0
- package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/cobre_qc_summary.py +95 -0
- package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/extract_cobre_phenotype.py +104 -0
- package/skills/06_fMRI_Neuroimaging/cobre-skill/scripts/reorganize_cobre.py +140 -0
- package/skills/06_fMRI_Neuroimaging/conn-tool/SKILL.md +180 -0
- package/skills/06_fMRI_Neuroimaging/dcm2nii/SKILL.md +189 -0
- package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/SKILL.md +183 -0
- package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/dmt_har_med_qc_summary.py +96 -0
- package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/extract_dmt_har_med_phenotype.py +121 -0
- package/skills/06_fMRI_Neuroimaging/dmt-har-med-skill/scripts/reorganize_dmt_har_med.py +125 -0
- package/skills/06_fMRI_Neuroimaging/dwi-skill/SKILL.md +359 -0
- package/skills/06_fMRI_Neuroimaging/fmri-skill/SKILL.md +371 -0
- package/skills/06_fMRI_Neuroimaging/fmriprep-tool/SKILL.md +228 -0
- package/skills/06_fMRI_Neuroimaging/freesurfer-tool/SKILL.md +286 -0
- package/skills/06_fMRI_Neuroimaging/freesurfer-tool/scripts/freesurfer_processor.py +145 -0
- package/skills/06_fMRI_Neuroimaging/fsl-tool/SKILL.md +208 -0
- package/skills/06_fMRI_Neuroimaging/hbn-skill/SKILL.md +271 -0
- package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/extract_hbn_phenotype.py +107 -0
- package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/hbn_qc_summary.py +96 -0
- package/skills/06_fMRI_Neuroimaging/hbn-skill/scripts/reorganize_hbn.py +150 -0
- package/skills/06_fMRI_Neuroimaging/hcpa-skill/SKILL.md +210 -0
- package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/extract_hcpa_phenotype.py +146 -0
- package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/hcpa_qc_summary.py +120 -0
- package/skills/06_fMRI_Neuroimaging/hcpa-skill/scripts/reorganize_hcpa.py +155 -0
- package/skills/06_fMRI_Neuroimaging/hcpd-skill/SKILL.md +210 -0
- package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/extract_hcpd_phenotype.py +148 -0
- package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/hcpd_qc_summary.py +125 -0
- package/skills/06_fMRI_Neuroimaging/hcpd-skill/scripts/reorganize_hcpd.py +146 -0
- package/skills/06_fMRI_Neuroimaging/hcpep-skill/SKILL.md +215 -0
- package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/extract_hcpep_phenotype.py +157 -0
- package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/hcpep_qc_summary.py +143 -0
- package/skills/06_fMRI_Neuroimaging/hcpep-skill/scripts/reorganize_hcpep.py +146 -0
- package/skills/06_fMRI_Neuroimaging/hcppipeline-tool/SKILL.md +217 -0
- package/skills/06_fMRI_Neuroimaging/hcpya-skill/SKILL.md +214 -0
- package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/extract_hcpya_phenotype.py +190 -0
- package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/hcpya_qc_summary.py +152 -0
- package/skills/06_fMRI_Neuroimaging/hcpya-skill/scripts/reorganize_hcpya.py +203 -0
- package/skills/06_fMRI_Neuroimaging/ixi-skill/SKILL.md +198 -0
- package/skills/06_fMRI_Neuroimaging/ixi-skill/scripts/ixi_qc_summary.py +137 -0
- package/skills/06_fMRI_Neuroimaging/ixi-skill/scripts/reorganize_ixi.py +190 -0
- package/skills/06_fMRI_Neuroimaging/mnd-skill/SKILL.md +191 -0
- package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/extract_mnd_phenotype.py +143 -0
- package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/mnd_qc_summary.py +120 -0
- package/skills/06_fMRI_Neuroimaging/mnd-skill/scripts/validate_mnd.py +107 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/SKILL.md +203 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/analyze_lesions.py +119 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/longitudinal_lesion.py +148 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/mschallenge_qc_summary.py +132 -0
- package/skills/06_fMRI_Neuroimaging/mschallenge-skill/scripts/validate_mschallenge.py +116 -0
- package/skills/06_fMRI_Neuroimaging/nibabel-skill/SKILL.md +184 -0
- package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/atlas_coordinate_reference.py +61 -0
- package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/freesurfer_io_reference.py +34 -0
- package/skills/06_fMRI_Neuroimaging/nibabel-skill/scripts/nifti_inspection_reference.py +35 -0
- package/skills/06_fMRI_Neuroimaging/nifd-skill/SKILL.md +205 -0
- package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/extract_nifd_phenotype.py +132 -0
- package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/nifd_qc_summary.py +111 -0
- package/skills/06_fMRI_Neuroimaging/nifd-skill/scripts/validate_nifd.py +111 -0
- package/skills/06_fMRI_Neuroimaging/nii2dcm/SKILL.md +143 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/SKILL.md +266 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/connectome_reference.py +65 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/denoise_timeseries_reference.py +58 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/hierarchical_parcellation_reference.py +53 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/kmeans_parcellation_reference.py +53 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/preprocess_bold_reference.py +76 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/rest_dictlearning_reference.py +56 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/rest_ica_reference.py +59 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/second_level_glm_reference.py +58 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/spacenet_classifier_reference.py +59 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/svm_classifier_reference.py +60 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/task_glm_reference.py +63 -0
- package/skills/06_fMRI_Neuroimaging/nilearn-tool/scripts/zalff_summary_reference.py +109 -0
- package/skills/06_fMRI_Neuroimaging/nsd-skill/SKILL.md +210 -0
- package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/extract_nsd_stimulus.py +171 -0
- package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/nsd_qc_summary.py +142 -0
- package/skills/06_fMRI_Neuroimaging/nsd-skill/scripts/validate_nsd.py +142 -0
- package/skills/06_fMRI_Neuroimaging/oasis-skill/SKILL.md +205 -0
- package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/extract_oasis_phenotype.py +126 -0
- package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/oasis_qc_summary.py +115 -0
- package/skills/06_fMRI_Neuroimaging/oasis-skill/scripts/validate_oasis.py +119 -0
- package/skills/06_fMRI_Neuroimaging/pet-skill/SKILL.md +173 -0
- package/skills/06_fMRI_Neuroimaging/pet-skill/scripts/compute_suvr.py +202 -0
- package/skills/06_fMRI_Neuroimaging/pnc-skill/SKILL.md +206 -0
- package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/extract_pnc_phenotype.py +136 -0
- package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/pnc_qc_summary.py +116 -0
- package/skills/06_fMRI_Neuroimaging/pnc-skill/scripts/validate_pnc.py +120 -0
- package/skills/06_fMRI_Neuroimaging/ppmi-skill/SKILL.md +209 -0
- package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/extract_ppmi_phenotype.py +138 -0
- package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/ppmi_qc_summary.py +111 -0
- package/skills/06_fMRI_Neuroimaging/ppmi-skill/scripts/validate_ppmi.py +117 -0
- package/skills/06_fMRI_Neuroimaging/qsiprep-tool/SKILL.md +320 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/SKILL.md +215 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/extract_rest_mdd_phenotype.py +132 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/harmonize_sites.py +152 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/rest_mdd_qc_summary.py +124 -0
- package/skills/06_fMRI_Neuroimaging/rest-mneta-mdd-skill/scripts/validate_rest_mdd.py +103 -0
- package/skills/06_fMRI_Neuroimaging/smri-skill/SKILL.md +302 -0
- package/skills/06_fMRI_Neuroimaging/tcp-skill/SKILL.md +204 -0
- package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/extract_tcp_phenotype.py +139 -0
- package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/tcp_qc_summary.py +111 -0
- package/skills/06_fMRI_Neuroimaging/tcp-skill/scripts/validate_tcp.py +99 -0
- package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/SKILL.md +217 -0
- package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/extract_ucla_cnp_phenotype.py +145 -0
- package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/ucla_cnp_qc_summary.py +111 -0
- package/skills/06_fMRI_Neuroimaging/ucla-cnp-skill/scripts/validate_ucla_cnp.py +113 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/SKILL.md +310 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/build_ukb_survival.py +210 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/extract_ukb_cases.py +308 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/extract_ukb_phenotype.py +232 -0
- package/skills/06_fMRI_Neuroimaging/ukb-skill/scripts/ukb_qc_summary.py +158 -0
- package/skills/06_fMRI_Neuroimaging/wmh-segmentation/SKILL.md +133 -0
- package/skills/07_Computational_Modeling/detrending/SKILL.md +118 -0
- package/skills/07_Computational_Modeling/dictlearning/SKILL.md +122 -0
- package/skills/07_Computational_Modeling/filtering/SKILL.md +121 -0
- package/skills/07_Computational_Modeling/glm/SKILL.md +153 -0
- package/skills/07_Computational_Modeling/hierarchical/SKILL.md +121 -0
- package/skills/07_Computational_Modeling/ica/SKILL.md +122 -0
- package/skills/07_Computational_Modeling/kmeans/SKILL.md +119 -0
- package/skills/07_Computational_Modeling/run_models/SKILL.md +427 -0
- package/skills/07_Computational_Modeling/spacenet/SKILL.md +122 -0
- package/skills/07_Computational_Modeling/svm/SKILL.md +120 -0
- package/skills/08_Computational_Neuroscience/brain_gnn/SKILL.md +183 -0
- package/skills/08_Computational_Neuroscience/dipy-tool/SKILL.md +239 -0
- package/skills/08_Computational_Neuroscience/dipy-tool/scripts/dti_metrics_reference.py +70 -0
- package/skills/08_Computational_Neuroscience/dipy-tool/scripts/load_and_mask_reference.py +76 -0
- package/skills/08_Computational_Neuroscience/dipy-tool/scripts/roi_stats_reference.py +59 -0
- package/skills/08_Computational_Neuroscience/fm_app/SKILL.md +195 -0
- package/skills/08_Computational_Neuroscience/neurostorm/SKILL.md +151 -0
- package/skills/13_Visualization/brain-visualization/SKILL.md +191 -0
- package/skills/13_Visualization/brain-visualization/scripts/connectome_reference.py +108 -0
- package/skills/13_Visualization/brain-visualization/scripts/freesurfer_ply_reference.py +54 -0
- package/skills/13_Visualization/brain-visualization/scripts/zalff_summary_reference.py +116 -0
- package/skills/13_Visualization/ethoclaw-paper-figure-layout/SKILL.md +78 -0
- package/skills/13_Visualization/ethoclaw-paper-figure-layout/assets/naturecomm_figures.tex +74 -0
- package/skills/13_Visualization/ethoclaw-paper-figure-layout/scripts/layout_results_foldered.py +579 -0
- package/skills/14_Writing/overleaf-skill/SKILL.md +184 -0
- package/skills/14_Writing/overleaf-skill/scripts/install.sh +30 -0
- package/skills/14_Writing/paper-writing/SKILL.md +146 -0
- package/skills/14_Writing/paper-writing/scripts/data_statement_templates.py +164 -0
- package/skills/14_Writing/paper-writing/scripts/figure_templates.py +315 -0
- package/skills/14_Writing/paper-writing/scripts/nature_figure_style.py +214 -0
- package/skills/14_Writing/paper-writing/scripts/section_phrasebank.py +246 -0
- package/skills/16_Animal_Behavior/deeplabcut/SKILL.md +154 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/3d-pose.md +89 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/maDLC.md +123 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/modelzoo.md +98 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/standard-pipeline.md +165 -0
- package/skills/16_Animal_Behavior/deeplabcut/references/utilities.md +146 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/SKILL.md +274 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/report_template_en.html +112 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/report_template_en.md +21 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/cluster-section.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/heatmap-section.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/integrated-interpretation.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/overview.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/project-summary.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/radar-section.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/raw-trajectory.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/sample-check.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/single-subject-section.md +3 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/assets/section_templates/stats-section.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/epm.md +52 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/fst.md +37 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/nor.md +39 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/oft.md +43 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/tcst.md +45 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/experiment-types/tst.md +36 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/input-types.md +59 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/interpretation-guardrails.md +45 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/metadata-schema.md +57 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/report-sections.md +86 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/references/section-selection-rules.md +169 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/build_report_manifest.py +27 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/render_report.py +34 -0
- package/skills/16_Animal_Behavior/ethoclaw-analysis-report/scripts/report_utils.py +1121 -0
- package/skills/16_Animal_Behavior/ethoclaw-animal-grounding/SKILL.md +390 -0
- package/skills/16_Animal_Behavior/ethoclaw-animal-grounding/reference_code.py +98 -0
- package/skills/16_Animal_Behavior/ethoclaw-animal-pose-estimation/SKILL.md +336 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/README.md +21 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/SKILL.md +41 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/batch_kinematic_generator.py +663 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/config.json +19 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/generate_kinematic_parameter.py +401 -0
- package/skills/16_Animal_Behavior/ethoclaw-kinematic-parameter-generator/kinematic_generator.py +265 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/SKILL.md +72 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/references/config.example.toml +56 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/scripts/cluster_all_params.py +232 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-clustermap-generate/scripts/cluster_all_params_from_config.py +236 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/SKILL.md +68 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/references/notes.md +5 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-radar-generate/scripts/plot_h5_radar.py +513 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/SKILL.md +52 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/config.toml +81 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/references/stats-rule.md +18 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_inspect.py +79 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_violin_batch.py +624 -0
- package/skills/16_Animal_Behavior/ethoclaw-multiparameter-violin-stats-generate/scripts/h5_violin_stats.py +438 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/SKILL.md +280 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/core_scripts/heatmap_trajectory.py +790 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/core_scripts/heatmap_velocity.py +855 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_2d.csv +101 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_2d.h5 +0 -0
- package/skills/16_Animal_Behavior/ethoclaw-trajectory-velocity-heatmap-generate/reference_data/reference_data_readme.md +126 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Reusable Nature-journal figure templates.
|
|
3
|
+
|
|
4
|
+
Each function creates a complete figure from data and saves it.
|
|
5
|
+
Derived from nature-skills/nature-figure (MIT License, Copyright 2026 Yuan Yizhe).
|
|
6
|
+
Source: https://github.com/Yuan1z0825/nature-skills
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
import matplotlib
|
|
11
|
+
matplotlib.use('Agg')
|
|
12
|
+
import matplotlib.pyplot as plt
|
|
13
|
+
import matplotlib as mpl
|
|
14
|
+
from matplotlib import gridspec
|
|
15
|
+
|
|
16
|
+
from nature_figure_style import (
|
|
17
|
+
apply_publication_style, DEFAULT_COLORS, DEFAULT_COLORS_NMI_PASTEL,
|
|
18
|
+
add_panel_label, is_dark, finalize_figure,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def make_grouped_bar(ax, categories, series, labels,
|
|
23
|
+
ylabel='Value', colors=None,
|
|
24
|
+
annotate=False, bar_width=0.8,
|
|
25
|
+
error_kw=None):
|
|
26
|
+
"""
|
|
27
|
+
Grouped bar chart.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
ax : matplotlib Axes
|
|
32
|
+
categories : list[str] — x-axis category names (length K)
|
|
33
|
+
series : list[array] — one array per group (each length K)
|
|
34
|
+
labels : list[str] — legend label per group
|
|
35
|
+
colors : list[str] | None
|
|
36
|
+
annotate : bool — print value above each bar
|
|
37
|
+
bar_width : float — total width for all bars in one category
|
|
38
|
+
error_kw : dict — passed to ax.bar
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
list[BarContainer]
|
|
43
|
+
"""
|
|
44
|
+
if colors is None:
|
|
45
|
+
colors = DEFAULT_COLORS
|
|
46
|
+
if error_kw is None:
|
|
47
|
+
error_kw = {'elinewidth': 2, 'capthick': 2, 'capsize': 10}
|
|
48
|
+
n_groups = len(series)
|
|
49
|
+
n_cats = len(categories)
|
|
50
|
+
w = bar_width / n_groups
|
|
51
|
+
x = np.arange(n_cats)
|
|
52
|
+
containers = []
|
|
53
|
+
for i, (vals, label, color) in enumerate(zip(series, labels, colors)):
|
|
54
|
+
offset = (i - (n_groups - 1) / 2) * w
|
|
55
|
+
bars = ax.bar(x + offset, vals, width=w, label=label,
|
|
56
|
+
color=color, edgecolor='black', linewidth=1.5,
|
|
57
|
+
error_kw=error_kw)
|
|
58
|
+
containers.append(bars)
|
|
59
|
+
if annotate:
|
|
60
|
+
for bar, val in zip(bars, vals):
|
|
61
|
+
ax.text(bar.get_x() + bar.get_width() / 2,
|
|
62
|
+
bar.get_height() + 0.01,
|
|
63
|
+
f'{val:.2f}', ha='center', va='bottom', fontsize=10)
|
|
64
|
+
ax.set_xticks(x)
|
|
65
|
+
ax.set_xticklabels(categories)
|
|
66
|
+
ax.set_ylabel(ylabel)
|
|
67
|
+
ax.legend()
|
|
68
|
+
return containers
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def make_trend(ax, x, y_series, labels,
|
|
72
|
+
colors=None, ylabel=None, xlabel=None,
|
|
73
|
+
show_shadow=False, shadow_alpha=0.15,
|
|
74
|
+
lw=2.5, marker='o', markersize=8):
|
|
75
|
+
"""
|
|
76
|
+
Multi-line trend plot.
|
|
77
|
+
|
|
78
|
+
Parameters
|
|
79
|
+
----------
|
|
80
|
+
x : array-like — shared x values
|
|
81
|
+
y_series : list[array] — one 1D array per line (or 2D for mean±std)
|
|
82
|
+
labels : list[str]
|
|
83
|
+
show_shadow : bool — fill_between ± std if y_series contains 2D arrays
|
|
84
|
+
"""
|
|
85
|
+
if colors is None:
|
|
86
|
+
colors = DEFAULT_COLORS
|
|
87
|
+
for y, label, color in zip(y_series, labels, colors):
|
|
88
|
+
y = np.asarray(y)
|
|
89
|
+
if y.ndim == 2:
|
|
90
|
+
mean, std = y.mean(0), y.std(0)
|
|
91
|
+
else:
|
|
92
|
+
mean, std = y, None
|
|
93
|
+
ax.plot(x, mean, color=color, lw=lw, marker=marker,
|
|
94
|
+
markersize=markersize, label=label)
|
|
95
|
+
if show_shadow and std is not None:
|
|
96
|
+
ax.fill_between(x, mean - std, mean + std,
|
|
97
|
+
color=color, alpha=shadow_alpha)
|
|
98
|
+
if ylabel:
|
|
99
|
+
ax.set_ylabel(ylabel)
|
|
100
|
+
if xlabel:
|
|
101
|
+
ax.set_xlabel(xlabel)
|
|
102
|
+
ax.legend()
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def make_forest_plot(ax, labels, estimates, ci_low, ci_high,
|
|
106
|
+
colors=None, ref=0.0, xlabel=None, xlim=None,
|
|
107
|
+
marker='o', markersize=5, lw=1.5):
|
|
108
|
+
"""Minimal forest plot for Nature-style clinical/statistical panels."""
|
|
109
|
+
y = np.arange(len(labels))[::-1]
|
|
110
|
+
if colors is None:
|
|
111
|
+
colors = ['#B64342'] * len(labels)
|
|
112
|
+
for yi, est, lo, hi, color in zip(y, estimates, ci_low, ci_high, colors):
|
|
113
|
+
ax.plot([lo, hi], [yi, yi], color=color, lw=lw)
|
|
114
|
+
ax.plot(est, yi, marker=marker, ms=markersize, color=color)
|
|
115
|
+
ax.axvline(ref, color='#767676', linestyle='--', linewidth=1.2, alpha=0.8)
|
|
116
|
+
ax.set_yticks(y)
|
|
117
|
+
ax.set_yticklabels(labels)
|
|
118
|
+
if xlabel:
|
|
119
|
+
ax.set_xlabel(xlabel)
|
|
120
|
+
if xlim is not None:
|
|
121
|
+
ax.set_xlim(xlim)
|
|
122
|
+
ax.spines['right'].set_visible(False)
|
|
123
|
+
ax.spines['top'].set_visible(False)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def make_heatmap(ax, matrix, x_labels=None, y_labels=None,
|
|
127
|
+
cmap='magma', cbar_label=None, annotate=False,
|
|
128
|
+
fmt='{:.2f}', fontsize=12):
|
|
129
|
+
"""2D heatmap with optional colorbar and cell annotations."""
|
|
130
|
+
im = ax.imshow(matrix, cmap=cmap, aspect='auto')
|
|
131
|
+
if cbar_label:
|
|
132
|
+
cbar = ax.figure.colorbar(im, ax=ax)
|
|
133
|
+
cbar.set_label(cbar_label)
|
|
134
|
+
if x_labels:
|
|
135
|
+
ax.set_xticks(range(len(x_labels)))
|
|
136
|
+
ax.set_xticklabels(x_labels, rotation=30, ha='right')
|
|
137
|
+
if y_labels:
|
|
138
|
+
ax.set_yticks(range(len(y_labels)))
|
|
139
|
+
ax.set_yticklabels(y_labels)
|
|
140
|
+
if annotate:
|
|
141
|
+
norm = mpl.colors.Normalize(vmin=matrix.min(), vmax=matrix.max())
|
|
142
|
+
cm_obj = plt.get_cmap(cmap)
|
|
143
|
+
for (i, j), val in np.ndenumerate(matrix):
|
|
144
|
+
r, g, b, _ = cm_obj(norm(val))
|
|
145
|
+
lum = 0.299 * r + 0.587 * g + 0.114 * b
|
|
146
|
+
color = 'white' if lum < 0.5 else 'black'
|
|
147
|
+
ax.text(j, i, fmt.format(val), ha='center', va='center',
|
|
148
|
+
fontsize=fontsize, color=color)
|
|
149
|
+
ax.set_frame_on(False)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
153
|
+
# Complete Figure Templates
|
|
154
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
155
|
+
|
|
156
|
+
def template_grouped_bar_with_legend_panel(methods, metrics, mean_dict, std_dict,
|
|
157
|
+
colors=None, out_path='./figures/comparison'):
|
|
158
|
+
"""
|
|
159
|
+
Multi-metric grouped bar chart with a dedicated legend panel.
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
methods : list[str] — method names
|
|
164
|
+
metrics : list[str] — metric names
|
|
165
|
+
mean_dict : dict[str,array] — metric -> array of means per method
|
|
166
|
+
std_dict : dict[str,array] — metric -> array of stds per method
|
|
167
|
+
colors : list[str] — one color per method
|
|
168
|
+
out_path : str — save path (no extension)
|
|
169
|
+
"""
|
|
170
|
+
apply_publication_style(font_size=24, axes_linewidth=3)
|
|
171
|
+
if colors is None:
|
|
172
|
+
colors = DEFAULT_COLORS[:len(methods)]
|
|
173
|
+
|
|
174
|
+
fig = plt.figure(figsize=(28, 6))
|
|
175
|
+
gs = gridspec.GridSpec(1, len(metrics) + 1)
|
|
176
|
+
|
|
177
|
+
handles, labels = None, None
|
|
178
|
+
for col, metric in enumerate(metrics):
|
|
179
|
+
ax = fig.add_subplot(gs[col])
|
|
180
|
+
bars = ax.bar(
|
|
181
|
+
range(len(methods)), mean_dict[metric],
|
|
182
|
+
yerr=std_dict[metric], capsize=5,
|
|
183
|
+
color=colors, label=methods,
|
|
184
|
+
error_kw={'elinewidth': 2, 'capthick': 2},
|
|
185
|
+
)
|
|
186
|
+
if col == 0:
|
|
187
|
+
handles, labels = ax.get_legend_handles_labels()
|
|
188
|
+
ax.set_xticks([])
|
|
189
|
+
y_vals = mean_dict[metric]
|
|
190
|
+
margin = (y_vals.max() - y_vals.min()) * 0.15
|
|
191
|
+
ax.set_ylim([y_vals.min() - margin, y_vals.max() + margin])
|
|
192
|
+
ax.set_ylabel(metric, fontsize=32)
|
|
193
|
+
|
|
194
|
+
ax_leg = fig.add_subplot(gs[-1])
|
|
195
|
+
ax_leg.legend(handles, labels, fontsize=28, loc='center', frameon=False)
|
|
196
|
+
ax_leg.set_axis_off()
|
|
197
|
+
|
|
198
|
+
return finalize_figure(fig, out_path, formats=['png', 'pdf'])
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def template_ablation_bar(configs, values, stds=None,
|
|
202
|
+
out_path='./figures/ablation'):
|
|
203
|
+
"""
|
|
204
|
+
Horizontal ablation bar chart with alpha-graduated colors.
|
|
205
|
+
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
208
|
+
configs : list[str] — ablation configuration names
|
|
209
|
+
values : array — performance values
|
|
210
|
+
stds : array|None — standard deviations
|
|
211
|
+
"""
|
|
212
|
+
apply_publication_style(font_size=24, axes_linewidth=3)
|
|
213
|
+
|
|
214
|
+
n = len(configs)
|
|
215
|
+
blue_rgb = (0.215686, 0.458824, 0.729412)
|
|
216
|
+
alphas = np.linspace(0.2, 1.0, n)
|
|
217
|
+
colors = [(blue_rgb[0], blue_rgb[1], blue_rgb[2], a) for a in alphas]
|
|
218
|
+
|
|
219
|
+
fig, ax = plt.subplots(figsize=(12, 6))
|
|
220
|
+
ax.barh(range(n), values, xerr=stds, color=colors, ecolor='k', capsize=5)
|
|
221
|
+
ax.set_yticks(range(n))
|
|
222
|
+
ax.set_yticklabels(configs)
|
|
223
|
+
ax.set_xlim([values.min() - 0.05, values.max() + 0.03])
|
|
224
|
+
ax.set_xlabel('Score', fontsize=32)
|
|
225
|
+
|
|
226
|
+
return finalize_figure(fig, out_path, formats=['png'])
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def template_multi_panel_trend(methods, x, y_dict, panel_names,
|
|
230
|
+
colors=None, out_path='./figures/trends'):
|
|
231
|
+
"""
|
|
232
|
+
Multi-panel trend plot with shared legend panel.
|
|
233
|
+
|
|
234
|
+
Parameters
|
|
235
|
+
----------
|
|
236
|
+
methods : list[str]
|
|
237
|
+
x : array — shared x values
|
|
238
|
+
y_dict : dict[str, list[array]] — panel_name -> list of y arrays per method
|
|
239
|
+
panel_names : list[str]
|
|
240
|
+
colors : list[str]
|
|
241
|
+
"""
|
|
242
|
+
apply_publication_style(font_size=15, axes_linewidth=2)
|
|
243
|
+
if colors is None:
|
|
244
|
+
colors = DEFAULT_COLORS[:len(methods)]
|
|
245
|
+
|
|
246
|
+
fig, axes = plt.subplots(1, len(panel_names) + 1, figsize=(18, 5))
|
|
247
|
+
handles, labels = None, None
|
|
248
|
+
|
|
249
|
+
for idx, (ax, name) in enumerate(zip(axes[:len(panel_names)], panel_names)):
|
|
250
|
+
for method, color in zip(methods, colors):
|
|
251
|
+
y = y_dict[name][method]
|
|
252
|
+
ax.plot(x, y, color=color, lw=2.5, marker='o', markersize=6, label=method)
|
|
253
|
+
ax.set_title(name, fontsize=18)
|
|
254
|
+
ax.set_xlabel('Epoch', fontsize=16)
|
|
255
|
+
ax.set_ylabel('Loss', fontsize=16)
|
|
256
|
+
if idx == 0:
|
|
257
|
+
handles, labels = ax.get_legend_handles_labels()
|
|
258
|
+
|
|
259
|
+
axes[-1].legend(handles, labels, fontsize=14, loc='center', frameon=False)
|
|
260
|
+
axes[-1].set_axis_off()
|
|
261
|
+
|
|
262
|
+
return finalize_figure(fig, out_path, formats=['png', 'pdf'])
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def template_dual_colormap_heatmap(matrix, methods, metrics,
|
|
266
|
+
out_path='./figures/heatmap'):
|
|
267
|
+
"""
|
|
268
|
+
Heatmap with dual colormaps (positive=Reds, negative=Blues_r).
|
|
269
|
+
|
|
270
|
+
Parameters
|
|
271
|
+
----------
|
|
272
|
+
matrix : 2D array — rows=methods, cols=metrics
|
|
273
|
+
methods : list[str]
|
|
274
|
+
metrics : list[str] — even indices positive, odd indices negative
|
|
275
|
+
"""
|
|
276
|
+
apply_publication_style(font_size=16, axes_linewidth=2)
|
|
277
|
+
|
|
278
|
+
fig, ax = plt.subplots(figsize=(10, 6))
|
|
279
|
+
n_rows, n_cols = matrix.shape
|
|
280
|
+
vmax = matrix.max(0)
|
|
281
|
+
|
|
282
|
+
for j in range(n_cols):
|
|
283
|
+
is_positive = (j % 2 == 0)
|
|
284
|
+
cmap = plt.cm.Reds if is_positive else plt.cm.Blues_r
|
|
285
|
+
cmap = cmap.copy()
|
|
286
|
+
norm = mpl.colors.Normalize(
|
|
287
|
+
vmin=0 if is_positive else vmax[j],
|
|
288
|
+
vmax=vmax[j] if is_positive else 0,
|
|
289
|
+
)
|
|
290
|
+
ax.imshow(matrix[:, j:j + 1], cmap=cmap, norm=norm,
|
|
291
|
+
aspect='auto', extent=[j - 0.5, j + 0.5, 0, n_rows], origin='lower')
|
|
292
|
+
|
|
293
|
+
for (i, j), val in np.ndenumerate(matrix):
|
|
294
|
+
is_positive = (j % 2 == 0)
|
|
295
|
+
cmap = plt.cm.Reds if is_positive else plt.cm.Blues_r
|
|
296
|
+
norm = mpl.colors.Normalize(
|
|
297
|
+
vmin=0 if is_positive else vmax[j],
|
|
298
|
+
vmax=vmax[j] if is_positive else 0,
|
|
299
|
+
)
|
|
300
|
+
r, g, b, _ = cmap(norm(val))
|
|
301
|
+
lum = 0.299 * r + 0.587 * g + 0.114 * b
|
|
302
|
+
color = 'white' if lum < 0.5 else 'black'
|
|
303
|
+
ax.text(j, i + 0.5, f'{val:.2f}', ha='center', va='center',
|
|
304
|
+
fontsize=13, color=color)
|
|
305
|
+
|
|
306
|
+
ax.set_xlim(-0.5, n_cols - 0.5)
|
|
307
|
+
ax.set_xticks(np.arange(n_cols))
|
|
308
|
+
ax.set_xticklabels(metrics, rotation=30, ha='right', fontsize=14)
|
|
309
|
+
ax.tick_params(axis='x', bottom=False, top=False, length=0)
|
|
310
|
+
ax.set_yticks(np.arange(n_rows) + 0.5)
|
|
311
|
+
ax.set_yticklabels(methods, fontsize=14)
|
|
312
|
+
ax.set_frame_on(False)
|
|
313
|
+
ax.invert_yaxis()
|
|
314
|
+
|
|
315
|
+
return finalize_figure(fig, out_path, formats=['png'])
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Nature-journal publication style constants and helper functions.
|
|
3
|
+
|
|
4
|
+
Derived from nature-skills/nature-figure (MIT License, Copyright 2026 Yuan Yizhe).
|
|
5
|
+
Source: https://github.com/Yuan1z0825/nature-skills
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import matplotlib
|
|
9
|
+
matplotlib.use('Agg')
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
import numpy as np
|
|
12
|
+
import os
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
17
|
+
# Color Palettes
|
|
18
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
PALETTE = {
|
|
21
|
+
"blue_main": "#0F4D92",
|
|
22
|
+
"blue_secondary": "#3775BA",
|
|
23
|
+
"green_1": "#DDF3DE",
|
|
24
|
+
"green_2": "#AADCA9",
|
|
25
|
+
"green_3": "#8BCF8B",
|
|
26
|
+
"red_1": "#F6CFCB",
|
|
27
|
+
"red_2": "#E9A6A1",
|
|
28
|
+
"red_strong": "#B64342",
|
|
29
|
+
"neutral_light": "#CFCECE",
|
|
30
|
+
"neutral_mid": "#767676",
|
|
31
|
+
"neutral_dark": "#4D4D4D",
|
|
32
|
+
"neutral_black": "#272727",
|
|
33
|
+
"gold": "#FFD700",
|
|
34
|
+
"teal": "#42949E",
|
|
35
|
+
"violet": "#9A4D8E",
|
|
36
|
+
"magenta":"#EA84DD",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
DEFAULT_COLORS = [
|
|
40
|
+
PALETTE["blue_main"],
|
|
41
|
+
PALETTE["green_3"],
|
|
42
|
+
PALETTE["red_strong"],
|
|
43
|
+
PALETTE["teal"],
|
|
44
|
+
PALETTE["violet"],
|
|
45
|
+
PALETTE["neutral_light"],
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
PALETTE_NMI_PASTEL = {
|
|
49
|
+
"baseline_dark": "#484878",
|
|
50
|
+
"baseline_mid": "#7884B4",
|
|
51
|
+
"baseline_soft": "#B4C0E4",
|
|
52
|
+
"ours_tiny": "#E4E4F0",
|
|
53
|
+
"ours_base": "#E4CCD8",
|
|
54
|
+
"ours_large": "#F0C0CC",
|
|
55
|
+
"bg_lilac": "#E0E0F0",
|
|
56
|
+
"bg_aqua": "#E0F0F0",
|
|
57
|
+
"bg_peach": "#F0E0D0",
|
|
58
|
+
"neutral_light": "#D8D8D8",
|
|
59
|
+
"neutral_mid": "#A8A8A8",
|
|
60
|
+
"neutral_dark": "#606060",
|
|
61
|
+
"delta_up": "#2E9E44",
|
|
62
|
+
"delta_down": "#E53935",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
DEFAULT_COLORS_NMI_PASTEL = [
|
|
66
|
+
PALETTE_NMI_PASTEL["baseline_dark"],
|
|
67
|
+
PALETTE_NMI_PASTEL["baseline_mid"],
|
|
68
|
+
PALETTE_NMI_PASTEL["baseline_soft"],
|
|
69
|
+
PALETTE_NMI_PASTEL["ours_tiny"],
|
|
70
|
+
PALETTE_NMI_PASTEL["ours_base"],
|
|
71
|
+
PALETTE_NMI_PASTEL["ours_large"],
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
PALETTE_NATURE_IMAGING = {
|
|
75
|
+
"bg": "#000000",
|
|
76
|
+
"context": "#B8B8B8",
|
|
77
|
+
"cyan": "#22D7E6",
|
|
78
|
+
"magenta": "#FF2AD4",
|
|
79
|
+
"white": "#FFFFFF",
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
PALETTE_NATURE_MATERIAL = {
|
|
83
|
+
"aqua": "#77D7D1",
|
|
84
|
+
"teal": "#33B5A5",
|
|
85
|
+
"lilac": "#B9A7E8",
|
|
86
|
+
"violet": "#7C6CCF",
|
|
87
|
+
"callout_red": "#E53935",
|
|
88
|
+
"neutral": "#D9D9D9",
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
PALETTE_NATURE_CLINICAL = {
|
|
92
|
+
"baseline": "#272727",
|
|
93
|
+
"week6": "#E28E2C",
|
|
94
|
+
"week13": "#D24B40",
|
|
95
|
+
"week26": "#5B8FD6",
|
|
96
|
+
"year1": "#7BAA5B",
|
|
97
|
+
"year2": "#C45AD6",
|
|
98
|
+
"group_band": "#F2E6D9",
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
PALETTE_NATURE_GENOMICS = {
|
|
102
|
+
"neutral_light": "#D8D8D8",
|
|
103
|
+
"neutral_mid": "#8F8F8F",
|
|
104
|
+
"wave1": "#D9544D",
|
|
105
|
+
"wave2": "#5B7FCA",
|
|
106
|
+
"wave3": "#B89BD9",
|
|
107
|
+
"outline": "#4D4D4D",
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
112
|
+
# Style Setup
|
|
113
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
114
|
+
|
|
115
|
+
def apply_publication_style(font_size=16, axes_linewidth=2.5, use_tex=False):
|
|
116
|
+
"""Apply Nature-style rcParams. Call once before creating any figures."""
|
|
117
|
+
plt.rcParams['font.family'] = 'sans-serif'
|
|
118
|
+
plt.rcParams['font.sans-serif'] = ['Arial', 'DejaVu Sans', 'Liberation Sans']
|
|
119
|
+
plt.rcParams['svg.fonttype'] = 'none'
|
|
120
|
+
plt.rcParams['font.size'] = font_size
|
|
121
|
+
plt.rcParams['axes.spines.right'] = False
|
|
122
|
+
plt.rcParams['axes.spines.top'] = False
|
|
123
|
+
plt.rcParams['axes.linewidth'] = axes_linewidth
|
|
124
|
+
plt.rcParams['legend.frameon'] = False
|
|
125
|
+
if use_tex:
|
|
126
|
+
plt.rcParams['text.usetex'] = True
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# Presets:
|
|
130
|
+
# Large bar panels: apply_publication_style(font_size=24, axes_linewidth=3)
|
|
131
|
+
# Compact figures: apply_publication_style(font_size=15, axes_linewidth=2)
|
|
132
|
+
# Dense multi-panels: apply_publication_style(font_size=8, axes_linewidth=1)
|
|
133
|
+
# LaTeX labels: apply_publication_style(use_tex=True)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
137
|
+
# Helper Functions
|
|
138
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
139
|
+
|
|
140
|
+
def is_dark(hex_color, threshold=128):
|
|
141
|
+
"""Return True if hex color is dark (use white text on it)."""
|
|
142
|
+
c = hex_color.lstrip('#')
|
|
143
|
+
r, g, b = int(c[0:2], 16), int(c[2:4], 16), int(c[4:6], 16)
|
|
144
|
+
return (0.299 * r + 0.587 * g + 0.114 * b) < threshold
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def add_panel_label(ax, label, x=-0.06, y=1.02, fontsize=14,
|
|
148
|
+
color='black', fontweight='bold'):
|
|
149
|
+
"""Place a Nature-style panel label near the top-left edge."""
|
|
150
|
+
ax.text(
|
|
151
|
+
x, y, label,
|
|
152
|
+
transform=ax.transAxes,
|
|
153
|
+
fontsize=fontsize,
|
|
154
|
+
fontweight=fontweight,
|
|
155
|
+
color=color,
|
|
156
|
+
ha='left',
|
|
157
|
+
va='bottom',
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def style_dark_image_ax(ax, facecolor='black'):
|
|
162
|
+
"""Prepare an axes for microscopy / rendering plates."""
|
|
163
|
+
ax.set_facecolor(facecolor)
|
|
164
|
+
ax.set_xticks([])
|
|
165
|
+
ax.set_yticks([])
|
|
166
|
+
for spine in ax.spines.values():
|
|
167
|
+
spine.set_visible(False)
|
|
168
|
+
return ax
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def annotate_bars(ax, bars, colors, fmt='{:.2f}', fontsize=32, offset=-0.10):
|
|
172
|
+
"""Add luminance-aware text labels on bars."""
|
|
173
|
+
for bar, color in zip(bars, colors):
|
|
174
|
+
c = color.lstrip('#')
|
|
175
|
+
r, g, b = int(c[0:2], 16) / 255, int(c[2:4], 16) / 255, int(c[4:6], 16) / 255
|
|
176
|
+
lum = 0.299 * r + 0.587 * g + 0.114 * b
|
|
177
|
+
textcolor = 'white' if lum < 0.5 else 'black'
|
|
178
|
+
value = bar.get_height()
|
|
179
|
+
ax.text(bar.get_x() + bar.get_width() / 2,
|
|
180
|
+
value + offset,
|
|
181
|
+
fmt.format(value),
|
|
182
|
+
ha='center', va='bottom',
|
|
183
|
+
fontsize=fontsize, color=textcolor)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def finalize_figure(fig, out_path, formats=None, dpi=300,
|
|
187
|
+
pad=2, bbox_inches=None, close=True):
|
|
188
|
+
"""
|
|
189
|
+
Apply tight_layout and save figure.
|
|
190
|
+
|
|
191
|
+
Parameters
|
|
192
|
+
----------
|
|
193
|
+
out_path : str — path without extension, or with extension
|
|
194
|
+
formats : list — e.g. ['png', 'pdf']. If None, uses extension of out_path.
|
|
195
|
+
dpi : int — 300 standard, 600 for dense bar panels
|
|
196
|
+
pad : float — tight_layout pad (2 default, 1 for compact multi-panel)
|
|
197
|
+
"""
|
|
198
|
+
fig.tight_layout(pad=pad)
|
|
199
|
+
base = Path(out_path)
|
|
200
|
+
os.makedirs(base.parent, exist_ok=True)
|
|
201
|
+
if formats is None:
|
|
202
|
+
formats = [base.suffix.lstrip('.') or 'png']
|
|
203
|
+
base = base.with_suffix('')
|
|
204
|
+
saved = []
|
|
205
|
+
for fmt in formats:
|
|
206
|
+
p = str(base) + f'.{fmt}'
|
|
207
|
+
kw = {}
|
|
208
|
+
if bbox_inches is not None:
|
|
209
|
+
kw['bbox_inches'] = bbox_inches
|
|
210
|
+
fig.savefig(p, dpi=dpi, **kw)
|
|
211
|
+
saved.append(p)
|
|
212
|
+
if close:
|
|
213
|
+
plt.close(fig)
|
|
214
|
+
return saved
|