scientific-writer 2.1.1__py3-none-any.whl → 2.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of scientific-writer might be problematic. Click here for more details.
- scientific_writer/.claude/settings.local.json +30 -0
- scientific_writer/.claude/skills/citation-management/SKILL.md +1046 -0
- scientific_writer/.claude/skills/citation-management/assets/bibtex_template.bib +264 -0
- scientific_writer/.claude/skills/citation-management/assets/citation_checklist.md +386 -0
- scientific_writer/.claude/skills/citation-management/references/bibtex_formatting.md +908 -0
- scientific_writer/.claude/skills/citation-management/references/citation_validation.md +794 -0
- scientific_writer/.claude/skills/citation-management/references/google_scholar_search.md +725 -0
- scientific_writer/.claude/skills/citation-management/references/metadata_extraction.md +870 -0
- scientific_writer/.claude/skills/citation-management/references/pubmed_search.md +839 -0
- scientific_writer/.claude/skills/citation-management/scripts/doi_to_bibtex.py +204 -0
- scientific_writer/.claude/skills/citation-management/scripts/extract_metadata.py +569 -0
- scientific_writer/.claude/skills/citation-management/scripts/format_bibtex.py +349 -0
- scientific_writer/.claude/skills/citation-management/scripts/search_google_scholar.py +282 -0
- scientific_writer/.claude/skills/citation-management/scripts/search_pubmed.py +398 -0
- scientific_writer/.claude/skills/citation-management/scripts/validate_citations.py +497 -0
- scientific_writer/.claude/skills/clinical-reports/IMPLEMENTATION_SUMMARY.md +641 -0
- scientific_writer/.claude/skills/clinical-reports/README.md +236 -0
- scientific_writer/.claude/skills/clinical-reports/SKILL.md +1088 -0
- scientific_writer/.claude/skills/clinical-reports/assets/case_report_template.md +352 -0
- scientific_writer/.claude/skills/clinical-reports/assets/clinical_trial_csr_template.md +353 -0
- scientific_writer/.claude/skills/clinical-reports/assets/clinical_trial_sae_template.md +359 -0
- scientific_writer/.claude/skills/clinical-reports/assets/consult_note_template.md +305 -0
- scientific_writer/.claude/skills/clinical-reports/assets/discharge_summary_template.md +453 -0
- scientific_writer/.claude/skills/clinical-reports/assets/hipaa_compliance_checklist.md +395 -0
- scientific_writer/.claude/skills/clinical-reports/assets/history_physical_template.md +305 -0
- scientific_writer/.claude/skills/clinical-reports/assets/lab_report_template.md +309 -0
- scientific_writer/.claude/skills/clinical-reports/assets/pathology_report_template.md +249 -0
- scientific_writer/.claude/skills/clinical-reports/assets/quality_checklist.md +338 -0
- scientific_writer/.claude/skills/clinical-reports/assets/radiology_report_template.md +318 -0
- scientific_writer/.claude/skills/clinical-reports/assets/soap_note_template.md +253 -0
- scientific_writer/.claude/skills/clinical-reports/references/case_report_guidelines.md +570 -0
- scientific_writer/.claude/skills/clinical-reports/references/clinical_trial_reporting.md +693 -0
- scientific_writer/.claude/skills/clinical-reports/references/data_presentation.md +530 -0
- scientific_writer/.claude/skills/clinical-reports/references/diagnostic_reports_standards.md +629 -0
- scientific_writer/.claude/skills/clinical-reports/references/medical_terminology.md +588 -0
- scientific_writer/.claude/skills/clinical-reports/references/patient_documentation.md +744 -0
- scientific_writer/.claude/skills/clinical-reports/references/peer_review_standards.md +585 -0
- scientific_writer/.claude/skills/clinical-reports/references/regulatory_compliance.md +577 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/check_deidentification.py +346 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/compliance_checker.py +78 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/extract_clinical_data.py +102 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/format_adverse_events.py +103 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/generate_report_template.py +163 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/terminology_validator.py +133 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/validate_case_report.py +334 -0
- scientific_writer/.claude/skills/clinical-reports/scripts/validate_trial_report.py +89 -0
- scientific_writer/.claude/skills/document-skills/docx/LICENSE.txt +30 -0
- scientific_writer/.claude/skills/document-skills/docx/SKILL.md +197 -0
- scientific_writer/.claude/skills/document-skills/docx/docx-js.md +350 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/pack.py +159 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/unpack.py +29 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validate.py +69 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/base.py +951 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/docx.py +274 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- scientific_writer/.claude/skills/document-skills/docx/ooxml.md +610 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/__init__.py +1 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/document.py +1276 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/comments.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsExtended.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsIds.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/templates/people.xml +3 -0
- scientific_writer/.claude/skills/document-skills/docx/scripts/utilities.py +374 -0
- scientific_writer/.claude/skills/document-skills/pdf/LICENSE.txt +30 -0
- scientific_writer/.claude/skills/document-skills/pdf/SKILL.md +294 -0
- scientific_writer/.claude/skills/document-skills/pdf/forms.md +205 -0
- scientific_writer/.claude/skills/document-skills/pdf/reference.md +612 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes.py +70 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/check_fillable_fields.py +12 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/create_validation_image.py +41 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/extract_form_field_info.py +152 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/fill_fillable_fields.py +114 -0
- scientific_writer/.claude/skills/document-skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- scientific_writer/.claude/skills/document-skills/pptx/LICENSE.txt +30 -0
- scientific_writer/.claude/skills/document-skills/pptx/SKILL.md +484 -0
- scientific_writer/.claude/skills/document-skills/pptx/html2pptx.md +625 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/pack.py +159 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/unpack.py +29 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validate.py +69 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/base.py +951 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- scientific_writer/.claude/skills/document-skills/pptx/ooxml.md +427 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/html2pptx.js +979 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/inventory.py +1020 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/rearrange.py +231 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/replace.py +385 -0
- scientific_writer/.claude/skills/document-skills/pptx/scripts/thumbnail.py +450 -0
- scientific_writer/.claude/skills/document-skills/xlsx/LICENSE.txt +30 -0
- scientific_writer/.claude/skills/document-skills/xlsx/SKILL.md +289 -0
- scientific_writer/.claude/skills/document-skills/xlsx/recalc.py +178 -0
- scientific_writer/.claude/skills/hypothesis-generation/SKILL.md +155 -0
- scientific_writer/.claude/skills/hypothesis-generation/assets/hypothesis_output_template.md +302 -0
- scientific_writer/.claude/skills/hypothesis-generation/references/experimental_design_patterns.md +327 -0
- scientific_writer/.claude/skills/hypothesis-generation/references/hypothesis_quality_criteria.md +196 -0
- scientific_writer/.claude/skills/hypothesis-generation/references/literature_search_strategies.md +505 -0
- scientific_writer/.claude/skills/latex-posters/README.md +417 -0
- scientific_writer/.claude/skills/latex-posters/SKILL.md +919 -0
- scientific_writer/.claude/skills/latex-posters/assets/baposter_template.tex +257 -0
- scientific_writer/.claude/skills/latex-posters/assets/beamerposter_template.tex +244 -0
- scientific_writer/.claude/skills/latex-posters/assets/poster_quality_checklist.md +358 -0
- scientific_writer/.claude/skills/latex-posters/assets/tikzposter_template.tex +251 -0
- scientific_writer/.claude/skills/latex-posters/references/latex_poster_packages.md +745 -0
- scientific_writer/.claude/skills/latex-posters/references/poster_content_guide.md +748 -0
- scientific_writer/.claude/skills/latex-posters/references/poster_design_principles.md +806 -0
- scientific_writer/.claude/skills/latex-posters/references/poster_layout_design.md +900 -0
- scientific_writer/.claude/skills/latex-posters/scripts/review_poster.sh +214 -0
- scientific_writer/.claude/skills/literature-review/SKILL.md +546 -0
- scientific_writer/.claude/skills/literature-review/assets/review_template.md +412 -0
- scientific_writer/.claude/skills/literature-review/references/citation_styles.md +166 -0
- scientific_writer/.claude/skills/literature-review/references/database_strategies.md +381 -0
- scientific_writer/.claude/skills/literature-review/scripts/generate_pdf.py +176 -0
- scientific_writer/.claude/skills/literature-review/scripts/search_databases.py +303 -0
- scientific_writer/.claude/skills/literature-review/scripts/verify_citations.py +222 -0
- scientific_writer/.claude/skills/markitdown/INSTALLATION_GUIDE.md +318 -0
- scientific_writer/.claude/skills/markitdown/LICENSE.txt +22 -0
- scientific_writer/.claude/skills/markitdown/OPENROUTER_INTEGRATION.md +359 -0
- scientific_writer/.claude/skills/markitdown/QUICK_REFERENCE.md +309 -0
- scientific_writer/.claude/skills/markitdown/README.md +184 -0
- scientific_writer/.claude/skills/markitdown/SKILL.md +450 -0
- scientific_writer/.claude/skills/markitdown/SKILL_SUMMARY.md +307 -0
- scientific_writer/.claude/skills/markitdown/assets/example_usage.md +463 -0
- scientific_writer/.claude/skills/markitdown/references/api_reference.md +399 -0
- scientific_writer/.claude/skills/markitdown/references/file_formats.md +542 -0
- scientific_writer/.claude/skills/markitdown/scripts/batch_convert.py +228 -0
- scientific_writer/.claude/skills/markitdown/scripts/convert_literature.py +283 -0
- scientific_writer/.claude/skills/markitdown/scripts/convert_with_ai.py +243 -0
- scientific_writer/.claude/skills/paper-2-web/SKILL.md +455 -0
- scientific_writer/.claude/skills/paper-2-web/references/installation.md +141 -0
- scientific_writer/.claude/skills/paper-2-web/references/paper2poster.md +346 -0
- scientific_writer/.claude/skills/paper-2-web/references/paper2video.md +305 -0
- scientific_writer/.claude/skills/paper-2-web/references/paper2web.md +187 -0
- scientific_writer/.claude/skills/paper-2-web/references/usage_examples.md +436 -0
- scientific_writer/.claude/skills/peer-review/SKILL.md +375 -0
- scientific_writer/.claude/skills/peer-review/references/common_issues.md +552 -0
- scientific_writer/.claude/skills/peer-review/references/reporting_standards.md +290 -0
- scientific_writer/.claude/skills/research-grants/README.md +285 -0
- scientific_writer/.claude/skills/research-grants/SKILL.md +896 -0
- scientific_writer/.claude/skills/research-grants/assets/budget_justification_template.md +453 -0
- scientific_writer/.claude/skills/research-grants/assets/nih_specific_aims_template.md +166 -0
- scientific_writer/.claude/skills/research-grants/assets/nsf_project_summary_template.md +92 -0
- scientific_writer/.claude/skills/research-grants/references/broader_impacts.md +392 -0
- scientific_writer/.claude/skills/research-grants/references/darpa_guidelines.md +636 -0
- scientific_writer/.claude/skills/research-grants/references/doe_guidelines.md +586 -0
- scientific_writer/.claude/skills/research-grants/references/nih_guidelines.md +851 -0
- scientific_writer/.claude/skills/research-grants/references/nsf_guidelines.md +570 -0
- scientific_writer/.claude/skills/research-grants/references/specific_aims_guide.md +458 -0
- scientific_writer/.claude/skills/research-lookup/README.md +116 -0
- scientific_writer/.claude/skills/research-lookup/SKILL.md +443 -0
- scientific_writer/.claude/skills/research-lookup/examples.py +174 -0
- scientific_writer/.claude/skills/research-lookup/lookup.py +93 -0
- scientific_writer/.claude/skills/research-lookup/research_lookup.py +335 -0
- scientific_writer/.claude/skills/research-lookup/scripts/research_lookup.py +261 -0
- scientific_writer/.claude/skills/scholar-evaluation/SKILL.md +254 -0
- scientific_writer/.claude/skills/scholar-evaluation/references/evaluation_framework.md +663 -0
- scientific_writer/.claude/skills/scholar-evaluation/scripts/calculate_scores.py +378 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/SKILL.md +530 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/common_biases.md +364 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/evidence_hierarchy.md +484 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/experimental_design.md +496 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/logical_fallacies.md +478 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/scientific_method.md +169 -0
- scientific_writer/.claude/skills/scientific-critical-thinking/references/statistical_pitfalls.md +506 -0
- scientific_writer/.claude/skills/scientific-schematics/SKILL.md +2035 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/block_diagram_template.tex +199 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/circuit_template.tex +159 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/flowchart_template.tex +161 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/pathway_template.tex +162 -0
- scientific_writer/.claude/skills/scientific-schematics/assets/tikz_styles.tex +422 -0
- scientific_writer/.claude/skills/scientific-schematics/references/best_practices.md +562 -0
- scientific_writer/.claude/skills/scientific-schematics/references/diagram_types.md +637 -0
- scientific_writer/.claude/skills/scientific-schematics/references/python_libraries.md +791 -0
- scientific_writer/.claude/skills/scientific-schematics/references/tikz_guide.md +734 -0
- scientific_writer/.claude/skills/scientific-schematics/scripts/circuit_generator.py +307 -0
- scientific_writer/.claude/skills/scientific-schematics/scripts/compile_tikz.py +292 -0
- scientific_writer/.claude/skills/scientific-schematics/scripts/generate_flowchart.py +281 -0
- scientific_writer/.claude/skills/scientific-schematics/scripts/pathway_diagram.py +406 -0
- scientific_writer/.claude/skills/scientific-writing/SKILL.md +443 -0
- scientific_writer/.claude/skills/scientific-writing/references/citation_styles.md +720 -0
- scientific_writer/.claude/skills/scientific-writing/references/figures_tables.md +806 -0
- scientific_writer/.claude/skills/scientific-writing/references/imrad_structure.md +658 -0
- scientific_writer/.claude/skills/scientific-writing/references/reporting_guidelines.md +748 -0
- scientific_writer/.claude/skills/scientific-writing/references/writing_principles.md +824 -0
- scientific_writer/.claude/skills/treatment-plans/README.md +483 -0
- scientific_writer/.claude/skills/treatment-plans/SKILL.md +817 -0
- scientific_writer/.claude/skills/treatment-plans/assets/chronic_disease_management_plan.tex +636 -0
- scientific_writer/.claude/skills/treatment-plans/assets/general_medical_treatment_plan.tex +616 -0
- scientific_writer/.claude/skills/treatment-plans/assets/mental_health_treatment_plan.tex +745 -0
- scientific_writer/.claude/skills/treatment-plans/assets/pain_management_plan.tex +770 -0
- scientific_writer/.claude/skills/treatment-plans/assets/perioperative_care_plan.tex +724 -0
- scientific_writer/.claude/skills/treatment-plans/assets/quality_checklist.md +471 -0
- scientific_writer/.claude/skills/treatment-plans/assets/rehabilitation_treatment_plan.tex +727 -0
- scientific_writer/.claude/skills/treatment-plans/references/goal_setting_frameworks.md +411 -0
- scientific_writer/.claude/skills/treatment-plans/references/intervention_guidelines.md +507 -0
- scientific_writer/.claude/skills/treatment-plans/references/regulatory_compliance.md +476 -0
- scientific_writer/.claude/skills/treatment-plans/references/specialty_specific_guidelines.md +607 -0
- scientific_writer/.claude/skills/treatment-plans/references/treatment_plan_standards.md +456 -0
- scientific_writer/.claude/skills/treatment-plans/scripts/check_completeness.py +318 -0
- scientific_writer/.claude/skills/treatment-plans/scripts/generate_template.py +244 -0
- scientific_writer/.claude/skills/treatment-plans/scripts/timeline_generator.py +369 -0
- scientific_writer/.claude/skills/treatment-plans/scripts/validate_treatment_plan.py +367 -0
- scientific_writer/.claude/skills/venue-templates/SKILL.md +590 -0
- scientific_writer/.claude/skills/venue-templates/assets/grants/nih_specific_aims.tex +235 -0
- scientific_writer/.claude/skills/venue-templates/assets/grants/nsf_proposal_template.tex +375 -0
- scientific_writer/.claude/skills/venue-templates/assets/journals/nature_article.tex +171 -0
- scientific_writer/.claude/skills/venue-templates/assets/journals/neurips_article.tex +283 -0
- scientific_writer/.claude/skills/venue-templates/assets/journals/plos_one.tex +317 -0
- scientific_writer/.claude/skills/venue-templates/assets/posters/beamerposter_academic.tex +311 -0
- scientific_writer/.claude/skills/venue-templates/references/conferences_formatting.md +564 -0
- scientific_writer/.claude/skills/venue-templates/references/grants_requirements.md +787 -0
- scientific_writer/.claude/skills/venue-templates/references/journals_formatting.md +486 -0
- scientific_writer/.claude/skills/venue-templates/references/posters_guidelines.md +628 -0
- scientific_writer/.claude/skills/venue-templates/scripts/customize_template.py +206 -0
- scientific_writer/.claude/skills/venue-templates/scripts/query_template.py +260 -0
- scientific_writer/.claude/skills/venue-templates/scripts/validate_format.py +255 -0
- scientific_writer/CLAUDE.md +748 -0
- scientific_writer/__init__.py +2 -2
- scientific_writer/api.py +14 -7
- scientific_writer/cli.py +12 -7
- scientific_writer/core.py +27 -5
- {scientific_writer-2.1.1.dist-info → scientific_writer-2.2.2.dist-info}/METADATA +5 -1
- scientific_writer-2.2.2.dist-info/RECORD +312 -0
- scientific_writer-2.1.1.dist-info/RECORD +0 -11
- {scientific_writer-2.1.1.dist-info → scientific_writer-2.2.2.dist-info}/WHEEL +0 -0
- {scientific_writer-2.1.1.dist-info → scientific_writer-2.2.2.dist-info}/entry_points.txt +0 -0
- {scientific_writer-2.1.1.dist-info → scientific_writer-2.2.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,2035 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scientific-schematics
|
|
3
|
+
description: "Create publication-quality scientific diagrams, flowcharts, and schematics using Python (graphviz, matplotlib, schemdraw, networkx). Specialized in neural network architectures, system diagrams, and flowcharts. Generates SVG/EPS in figures/ folder with automated quality verification."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Scientific Schematics and Diagrams
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Scientific schematics and diagrams transform complex concepts into clear visual representations for publication. Generate neural network architectures, flowcharts, circuit diagrams, biological pathways, and system diagrams using best-in-class Python libraries. **All diagrams are created as SVG/EPS files, stored in the figures/ subfolder, and referenced in papers/posters** - never embedded directly in LaTeX.
|
|
11
|
+
|
|
12
|
+
## Zero-Shot Diagram Generation Workflow
|
|
13
|
+
|
|
14
|
+
**Standard workflow for ALL diagrams:**
|
|
15
|
+
|
|
16
|
+
1. **Analyze requirements** - Identify diagram type and components
|
|
17
|
+
2. **Choose optimal library** - Select best tool for the specific diagram type
|
|
18
|
+
3. **Generate vector graphic** - Create SVG/EPS with proper spacing and layout
|
|
19
|
+
4. **Store in figures/** - Save to `figures/` subfolder with descriptive name
|
|
20
|
+
5. **Run quality checks** - Verify no overlaps, good contrast, proper resolution
|
|
21
|
+
6. **Reference in document** - Use `\includegraphics{figures/diagram_name.pdf}` in LaTeX
|
|
22
|
+
|
|
23
|
+
**Key principle:** Generate standalone vector graphics first, then integrate into documents.
|
|
24
|
+
|
|
25
|
+
## When to Use This Skill
|
|
26
|
+
|
|
27
|
+
This skill should be used when:
|
|
28
|
+
- Creating neural network architecture diagrams (Transformers, CNNs, RNNs, etc.)
|
|
29
|
+
- Illustrating system architectures and data flow diagrams
|
|
30
|
+
- Drawing methodology flowcharts for study design (CONSORT, PRISMA)
|
|
31
|
+
- Visualizing algorithm workflows and processing pipelines
|
|
32
|
+
- Creating circuit diagrams and electrical schematics
|
|
33
|
+
- Depicting biological pathways and molecular interactions
|
|
34
|
+
- Generating network topologies and hierarchical structures
|
|
35
|
+
- Illustrating conceptual frameworks and theoretical models
|
|
36
|
+
- Designing block diagrams for technical papers
|
|
37
|
+
|
|
38
|
+
## Best Libraries by Diagram Type
|
|
39
|
+
|
|
40
|
+
Choose the optimal library for your specific diagram type:
|
|
41
|
+
|
|
42
|
+
### Neural Network Architectures (Transformers, CNNs, etc.)
|
|
43
|
+
**Best library:** `graphviz` via Python's `pygraphviz` or `pydot`
|
|
44
|
+
- Excellent automatic layout algorithms
|
|
45
|
+
- Clean, professional appearance
|
|
46
|
+
- Perfect for layer stacks and connections
|
|
47
|
+
- Handles complex cross-connections well
|
|
48
|
+
|
|
49
|
+
**Alternative:** Custom `matplotlib` with careful positioning
|
|
50
|
+
- More control over exact placement
|
|
51
|
+
- Better for highly customized designs
|
|
52
|
+
- Requires more manual positioning
|
|
53
|
+
|
|
54
|
+
### Flowcharts and Process Diagrams
|
|
55
|
+
**Best library:** `graphviz` with `dot` or `flowchart` layout
|
|
56
|
+
- Automatic optimal positioning
|
|
57
|
+
- Standard flowchart shapes
|
|
58
|
+
- Clean arrow routing
|
|
59
|
+
- Minimal overlap issues
|
|
60
|
+
|
|
61
|
+
**Alternative:** `diagrams` library (for cloud/system architecture style)
|
|
62
|
+
|
|
63
|
+
### Circuit Diagrams
|
|
64
|
+
**Best library:** `schemdraw`
|
|
65
|
+
- Purpose-built for electrical circuits
|
|
66
|
+
- Extensive component library
|
|
67
|
+
- Automatic wire routing
|
|
68
|
+
- Professional engineering standard output
|
|
69
|
+
|
|
70
|
+
### Biological Pathways
|
|
71
|
+
**Best library:** `networkx` with custom rendering
|
|
72
|
+
- Graph-based pathway representation
|
|
73
|
+
- Algorithm-driven layout
|
|
74
|
+
- Flexible node/edge styling
|
|
75
|
+
|
|
76
|
+
### Block Diagrams and System Architecture
|
|
77
|
+
**Best library:** `graphviz` or `diagrams`
|
|
78
|
+
- Clean hierarchical layouts
|
|
79
|
+
- Automatic spacing
|
|
80
|
+
- Professional appearance
|
|
81
|
+
|
|
82
|
+
## Zero-Shot Examples for Common Diagram Types
|
|
83
|
+
|
|
84
|
+
### Example 1: Transformer Architecture (Neural Network)
|
|
85
|
+
|
|
86
|
+
Creating a Transformer encoder-decoder diagram like in "Attention Is All You Need":
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
import graphviz
|
|
90
|
+
from pathlib import Path
|
|
91
|
+
|
|
92
|
+
def create_transformer_diagram(output_dir='figures'):
|
|
93
|
+
"""
|
|
94
|
+
Create a Transformer architecture diagram.
|
|
95
|
+
Zero-shot generation with automatic layout.
|
|
96
|
+
"""
|
|
97
|
+
Path(output_dir).mkdir(exist_ok=True)
|
|
98
|
+
|
|
99
|
+
# Create directed graph with TB (top-to-bottom) layout
|
|
100
|
+
dot = graphviz.Digraph(
|
|
101
|
+
'transformer',
|
|
102
|
+
format='pdf',
|
|
103
|
+
graph_attr={
|
|
104
|
+
'rankdir': 'BT', # Bottom to top (like the original paper)
|
|
105
|
+
'splines': 'ortho', # Orthogonal edges
|
|
106
|
+
'nodesep': '0.5',
|
|
107
|
+
'ranksep': '0.8',
|
|
108
|
+
'bgcolor': 'white',
|
|
109
|
+
'dpi': '300'
|
|
110
|
+
},
|
|
111
|
+
node_attr={
|
|
112
|
+
'shape': 'box',
|
|
113
|
+
'style': 'rounded,filled',
|
|
114
|
+
'fillcolor': 'lightgray',
|
|
115
|
+
'fontname': 'Arial',
|
|
116
|
+
'fontsize': '11',
|
|
117
|
+
'width': '2.5',
|
|
118
|
+
'height': '0.5'
|
|
119
|
+
},
|
|
120
|
+
edge_attr={
|
|
121
|
+
'color': 'black',
|
|
122
|
+
'penwidth': '1.5'
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# ENCODER STACK (left side)
|
|
127
|
+
with dot.subgraph(name='cluster_encoder') as enc:
|
|
128
|
+
enc.attr(label='Encoder', fontsize='14', fontname='Arial-Bold')
|
|
129
|
+
enc.attr(style='rounded', color='blue', penwidth='2')
|
|
130
|
+
|
|
131
|
+
# Encoder layers (bottom to top)
|
|
132
|
+
enc.node('enc_input_emb', 'Input Embedding', fillcolor='#E8F4F8')
|
|
133
|
+
enc.node('enc_pos', 'Positional Encoding', fillcolor='#E8F4F8')
|
|
134
|
+
enc.node('enc_mha', 'Multi-Head\nAttention', fillcolor='#B3D9E6')
|
|
135
|
+
enc.node('enc_an1', 'Add & Norm', fillcolor='#CCE5FF')
|
|
136
|
+
enc.node('enc_ff', 'Feed Forward', fillcolor='#B3D9E6')
|
|
137
|
+
enc.node('enc_an2', 'Add & Norm', fillcolor='#CCE5FF')
|
|
138
|
+
|
|
139
|
+
# Encoder flow
|
|
140
|
+
enc.edge('enc_input_emb', 'enc_pos')
|
|
141
|
+
enc.edge('enc_pos', 'enc_mha')
|
|
142
|
+
enc.edge('enc_mha', 'enc_an1')
|
|
143
|
+
enc.edge('enc_an1', 'enc_ff')
|
|
144
|
+
enc.edge('enc_ff', 'enc_an2')
|
|
145
|
+
|
|
146
|
+
# DECODER STACK (right side)
|
|
147
|
+
with dot.subgraph(name='cluster_decoder') as dec:
|
|
148
|
+
dec.attr(label='Decoder', fontsize='14', fontname='Arial-Bold')
|
|
149
|
+
dec.attr(style='rounded', color='red', penwidth='2')
|
|
150
|
+
|
|
151
|
+
# Decoder layers (bottom to top)
|
|
152
|
+
dec.node('dec_output_emb', 'Output Embedding', fillcolor='#FFE8E8')
|
|
153
|
+
dec.node('dec_pos', 'Positional Encoding', fillcolor='#FFE8E8')
|
|
154
|
+
dec.node('dec_mmha', 'Masked Self-\nAttention', fillcolor='#FFB3B3')
|
|
155
|
+
dec.node('dec_an1', 'Add & Norm', fillcolor='#FFCCCC')
|
|
156
|
+
dec.node('dec_cross', 'Cross-Attention', fillcolor='#FFB3B3')
|
|
157
|
+
dec.node('dec_an2', 'Add & Norm', fillcolor='#FFCCCC')
|
|
158
|
+
dec.node('dec_ff', 'Feed Forward', fillcolor='#FFB3B3')
|
|
159
|
+
dec.node('dec_an3', 'Add & Norm', fillcolor='#FFCCCC')
|
|
160
|
+
dec.node('dec_linear', 'Linear & Softmax', fillcolor='#FF9999')
|
|
161
|
+
dec.node('dec_output', 'Output\nProbabilities', fillcolor='#FFE8E8')
|
|
162
|
+
|
|
163
|
+
# Decoder flow
|
|
164
|
+
dec.edge('dec_output_emb', 'dec_pos')
|
|
165
|
+
dec.edge('dec_pos', 'dec_mmha')
|
|
166
|
+
dec.edge('dec_mmha', 'dec_an1')
|
|
167
|
+
dec.edge('dec_an1', 'dec_cross')
|
|
168
|
+
dec.edge('dec_cross', 'dec_an2')
|
|
169
|
+
dec.edge('dec_an2', 'dec_ff')
|
|
170
|
+
dec.edge('dec_ff', 'dec_an3')
|
|
171
|
+
dec.edge('dec_an3', 'dec_linear')
|
|
172
|
+
dec.edge('dec_linear', 'dec_output')
|
|
173
|
+
|
|
174
|
+
# Cross-attention connection (encoder to decoder)
|
|
175
|
+
dot.edge('enc_an2', 'dec_cross',
|
|
176
|
+
style='dashed',
|
|
177
|
+
color='purple',
|
|
178
|
+
label=' context ',
|
|
179
|
+
fontsize='9')
|
|
180
|
+
|
|
181
|
+
# Input and output labels
|
|
182
|
+
dot.node('input_seq', 'Input Sequence',
|
|
183
|
+
shape='ellipse', fillcolor='lightgreen')
|
|
184
|
+
dot.node('target_seq', 'Target Sequence',
|
|
185
|
+
shape='ellipse', fillcolor='lightgreen')
|
|
186
|
+
|
|
187
|
+
dot.edge('input_seq', 'enc_input_emb')
|
|
188
|
+
dot.edge('target_seq', 'dec_output_emb')
|
|
189
|
+
|
|
190
|
+
# Render to files
|
|
191
|
+
output_path = f'{output_dir}/transformer_architecture'
|
|
192
|
+
dot.render(output_path, cleanup=True)
|
|
193
|
+
|
|
194
|
+
# Also save as SVG and EPS
|
|
195
|
+
dot.format = 'svg'
|
|
196
|
+
dot.render(output_path, cleanup=True)
|
|
197
|
+
dot.format = 'eps'
|
|
198
|
+
dot.render(output_path, cleanup=True)
|
|
199
|
+
|
|
200
|
+
print(f"✓ Transformer diagram created:")
|
|
201
|
+
print(f" - {output_path}.pdf")
|
|
202
|
+
print(f" - {output_path}.svg")
|
|
203
|
+
print(f" - {output_path}.eps")
|
|
204
|
+
|
|
205
|
+
return f"{output_path}.pdf"
|
|
206
|
+
|
|
207
|
+
# Usage
|
|
208
|
+
if __name__ == '__main__':
|
|
209
|
+
diagram_path = create_transformer_diagram('figures')
|
|
210
|
+
|
|
211
|
+
# Run quality checks
|
|
212
|
+
from quality_checker import run_quality_checks
|
|
213
|
+
run_quality_checks(diagram_path.replace('.pdf', '.png'))
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**LaTeX integration:**
|
|
217
|
+
```latex
|
|
218
|
+
\begin{figure}[htbp]
|
|
219
|
+
\centering
|
|
220
|
+
\includegraphics[width=0.9\textwidth]{figures/transformer_architecture.pdf}
|
|
221
|
+
\caption{Transformer encoder-decoder architecture showing multi-head attention,
|
|
222
|
+
feed-forward layers, and cross-attention mechanism.}
|
|
223
|
+
\label{fig:transformer}
|
|
224
|
+
\end{figure}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Example 2: Simple Flowchart (CONSORT-style)
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
import graphviz
|
|
231
|
+
from pathlib import Path
|
|
232
|
+
|
|
233
|
+
def create_consort_flowchart(output_dir='figures'):
|
|
234
|
+
"""Create a CONSORT participant flow diagram."""
|
|
235
|
+
Path(output_dir).mkdir(exist_ok=True)
|
|
236
|
+
|
|
237
|
+
dot = graphviz.Digraph(
|
|
238
|
+
'consort',
|
|
239
|
+
format='pdf',
|
|
240
|
+
graph_attr={
|
|
241
|
+
'rankdir': 'TB',
|
|
242
|
+
'splines': 'ortho',
|
|
243
|
+
'nodesep': '0.6',
|
|
244
|
+
'ranksep': '0.8',
|
|
245
|
+
'bgcolor': 'white'
|
|
246
|
+
},
|
|
247
|
+
node_attr={
|
|
248
|
+
'shape': 'box',
|
|
249
|
+
'style': 'rounded,filled',
|
|
250
|
+
'fillcolor': '#E8F4F8',
|
|
251
|
+
'fontname': 'Arial',
|
|
252
|
+
'fontsize': '10',
|
|
253
|
+
'width': '3',
|
|
254
|
+
'height': '0.6'
|
|
255
|
+
}
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
# Enrollment
|
|
259
|
+
dot.node('assessed', 'Assessed for eligibility\n(n=500)')
|
|
260
|
+
dot.node('excluded', 'Excluded (n=150)\n• Age < 18: n=80\n• Declined: n=50\n• Other: n=20')
|
|
261
|
+
dot.node('randomized', 'Randomized\n(n=350)')
|
|
262
|
+
|
|
263
|
+
# Allocation
|
|
264
|
+
dot.node('treatment', 'Allocated to treatment\n(n=175)', fillcolor='#C8E6C9')
|
|
265
|
+
dot.node('control', 'Allocated to control\n(n=175)', fillcolor='#FFECB3')
|
|
266
|
+
|
|
267
|
+
# Follow-up
|
|
268
|
+
dot.node('treat_lost', 'Lost to follow-up (n=15)', fillcolor='#FFCDD2')
|
|
269
|
+
dot.node('ctrl_lost', 'Lost to follow-up (n=10)', fillcolor='#FFCDD2')
|
|
270
|
+
|
|
271
|
+
# Analysis
|
|
272
|
+
dot.node('treat_analyzed', 'Analyzed (n=160)', fillcolor='#C8E6C9')
|
|
273
|
+
dot.node('ctrl_analyzed', 'Analyzed (n=165)', fillcolor='#FFECB3')
|
|
274
|
+
|
|
275
|
+
# Connect nodes
|
|
276
|
+
dot.edge('assessed', 'excluded')
|
|
277
|
+
dot.edge('assessed', 'randomized')
|
|
278
|
+
dot.edge('randomized', 'treatment')
|
|
279
|
+
dot.edge('randomized', 'control')
|
|
280
|
+
dot.edge('treatment', 'treat_lost')
|
|
281
|
+
dot.edge('treatment', 'treat_analyzed')
|
|
282
|
+
dot.edge('control', 'ctrl_lost')
|
|
283
|
+
dot.edge('control', 'ctrl_analyzed')
|
|
284
|
+
|
|
285
|
+
# Render
|
|
286
|
+
output_path = f'{output_dir}/consort_flowchart'
|
|
287
|
+
dot.render(output_path, cleanup=True)
|
|
288
|
+
|
|
289
|
+
print(f"✓ CONSORT flowchart created: {output_path}.pdf")
|
|
290
|
+
return f"{output_path}.pdf"
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Example 3: CNN Architecture
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
def create_cnn_architecture(output_dir='figures'):
|
|
297
|
+
"""Create a CNN architecture diagram."""
|
|
298
|
+
dot = graphviz.Digraph(
|
|
299
|
+
'cnn',
|
|
300
|
+
format='pdf',
|
|
301
|
+
graph_attr={'rankdir': 'LR', 'bgcolor': 'white'}
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
# Define layers
|
|
305
|
+
layers = [
|
|
306
|
+
('input', 'Input\n32×32×3', '#FFE8E8'),
|
|
307
|
+
('conv1', 'Conv 3×3\n32 filters', '#B3D9E6'),
|
|
308
|
+
('pool1', 'MaxPool\n2×2', '#FFE5B3'),
|
|
309
|
+
('conv2', 'Conv 3×3\n64 filters', '#B3D9E6'),
|
|
310
|
+
('pool2', 'MaxPool\n2×2', '#FFE5B3'),
|
|
311
|
+
('flatten', 'Flatten', '#D4E8D4'),
|
|
312
|
+
('fc1', 'FC 128', '#C8B3E6'),
|
|
313
|
+
('fc2', 'FC 10', '#C8B3E6'),
|
|
314
|
+
('softmax', 'Softmax', '#FFC8C8')
|
|
315
|
+
]
|
|
316
|
+
|
|
317
|
+
# Create nodes
|
|
318
|
+
for node_id, label, color in layers:
|
|
319
|
+
dot.node(node_id, label,
|
|
320
|
+
shape='box', style='rounded,filled',
|
|
321
|
+
fillcolor=color, fontname='Arial')
|
|
322
|
+
|
|
323
|
+
# Connect layers
|
|
324
|
+
for i in range(len(layers) - 1):
|
|
325
|
+
dot.edge(layers[i][0], layers[i+1][0])
|
|
326
|
+
|
|
327
|
+
output_path = f'{output_dir}/cnn_architecture'
|
|
328
|
+
dot.render(output_path, cleanup=True)
|
|
329
|
+
|
|
330
|
+
print(f"✓ CNN diagram created: {output_path}.pdf")
|
|
331
|
+
return f"{output_path}.pdf"
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Core Capabilities
|
|
335
|
+
|
|
336
|
+
### 1. Diagram Types Supported
|
|
337
|
+
|
|
338
|
+
**Neural Network Architectures**
|
|
339
|
+
- Transformer encoder-decoder models
|
|
340
|
+
- Convolutional Neural Networks (CNNs)
|
|
341
|
+
- Recurrent networks (LSTM, GRU)
|
|
342
|
+
- Attention mechanisms and variants
|
|
343
|
+
- Custom deep learning architectures
|
|
344
|
+
|
|
345
|
+
**Methodology Flowcharts**
|
|
346
|
+
- CONSORT participant flow diagrams
|
|
347
|
+
- PRISMA systematic review flows
|
|
348
|
+
- Data processing pipelines
|
|
349
|
+
- Algorithm workflows
|
|
350
|
+
- Subject enrollment flows
|
|
351
|
+
|
|
352
|
+
**Circuit Diagrams**
|
|
353
|
+
- Analog and digital electronic circuits
|
|
354
|
+
- Signal processing block diagrams
|
|
355
|
+
- Control system diagrams
|
|
356
|
+
|
|
357
|
+
**Biological Diagrams**
|
|
358
|
+
- Signaling pathways
|
|
359
|
+
- Metabolic pathway diagrams
|
|
360
|
+
- Gene regulatory networks
|
|
361
|
+
- Protein interaction networks
|
|
362
|
+
|
|
363
|
+
**System Architecture Diagrams**
|
|
364
|
+
- Software architecture and components
|
|
365
|
+
- Data flow diagrams
|
|
366
|
+
- Network topology diagrams
|
|
367
|
+
- Hierarchical organization charts
|
|
368
|
+
|
|
369
|
+
## Required Libraries and Installation
|
|
370
|
+
|
|
371
|
+
### Primary Library: Graphviz (Recommended for 90% of diagrams)
|
|
372
|
+
|
|
373
|
+
Graphviz is the best tool for most scientific diagrams due to automatic layout, clean rendering, and zero-overlap guarantee.
|
|
374
|
+
|
|
375
|
+
**Installation:**
|
|
376
|
+
```bash
|
|
377
|
+
# Install Graphviz binary (required)
|
|
378
|
+
# macOS
|
|
379
|
+
brew install graphviz
|
|
380
|
+
|
|
381
|
+
# Ubuntu/Debian
|
|
382
|
+
sudo apt-get install graphviz
|
|
383
|
+
|
|
384
|
+
# Install Python bindings
|
|
385
|
+
pip install graphviz
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Why Graphviz is optimal:**
|
|
389
|
+
- ✓ Automatic optimal layout (no manual positioning needed)
|
|
390
|
+
- ✓ Zero overlaps guaranteed by layout algorithms
|
|
391
|
+
- ✓ Professional appearance out of the box
|
|
392
|
+
- ✓ Supports complex hierarchies and cross-connections
|
|
393
|
+
- ✓ Native SVG, PDF, EPS output
|
|
394
|
+
- ✓ Minimal code for maximum quality
|
|
395
|
+
|
|
396
|
+
### Specialized Libraries
|
|
397
|
+
|
|
398
|
+
**Schemdraw** - Circuit diagrams only
|
|
399
|
+
```bash
|
|
400
|
+
pip install schemdraw
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**NetworkX** - Complex network analysis + visualization
|
|
404
|
+
```bash
|
|
405
|
+
pip install networkx matplotlib
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
**Matplotlib** - Custom manual diagrams (when you need exact control)
|
|
409
|
+
```bash
|
|
410
|
+
pip install matplotlib
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## Quick Start Guide for Zero-Shot Diagram Creation
|
|
414
|
+
|
|
415
|
+
Follow this systematic approach for any diagram type:
|
|
416
|
+
|
|
417
|
+
### Step 1: Identify Diagram Structure
|
|
418
|
+
|
|
419
|
+
Ask yourself:
|
|
420
|
+
- **Is it a hierarchy?** → Use `rankdir='TB'` or `'BT'` (top-to-bottom or bottom-to-top)
|
|
421
|
+
- **Is it a sequence?** → Use `rankdir='LR'` (left-to-right)
|
|
422
|
+
- **Does it have parallel branches?** → Use subgraphs/clusters
|
|
423
|
+
- **Does it have cross-connections?** → Graphviz handles this automatically
|
|
424
|
+
|
|
425
|
+
### Step 2: Set Up Base Template
|
|
426
|
+
|
|
427
|
+
Start with this template and customize:
|
|
428
|
+
|
|
429
|
+
```python
|
|
430
|
+
import graphviz
|
|
431
|
+
from pathlib import Path
|
|
432
|
+
|
|
433
|
+
def create_diagram(output_dir='figures', diagram_name='my_diagram'):
|
|
434
|
+
"""Universal diagram creation template."""
|
|
435
|
+
Path(output_dir).mkdir(exist_ok=True, parents=True)
|
|
436
|
+
|
|
437
|
+
dot = graphviz.Digraph(
|
|
438
|
+
name=diagram_name,
|
|
439
|
+
format='pdf',
|
|
440
|
+
graph_attr={
|
|
441
|
+
'rankdir': 'TB', # TB, BT, LR, or RL
|
|
442
|
+
'splines': 'ortho', # ortho (straight) or curved
|
|
443
|
+
'nodesep': '0.6', # horizontal spacing
|
|
444
|
+
'ranksep': '0.8', # vertical spacing
|
|
445
|
+
'bgcolor': 'white',
|
|
446
|
+
'dpi': '300'
|
|
447
|
+
},
|
|
448
|
+
node_attr={
|
|
449
|
+
'shape': 'box', # box, ellipse, diamond, etc.
|
|
450
|
+
'style': 'rounded,filled',
|
|
451
|
+
'fillcolor': 'lightgray',
|
|
452
|
+
'fontname': 'Arial',
|
|
453
|
+
'fontsize': '11',
|
|
454
|
+
'margin': '0.2',
|
|
455
|
+
'width': '2', # minimum width
|
|
456
|
+
'height': '0.5' # minimum height
|
|
457
|
+
},
|
|
458
|
+
edge_attr={
|
|
459
|
+
'color': 'black',
|
|
460
|
+
'penwidth': '1.5',
|
|
461
|
+
'arrowsize': '0.8'
|
|
462
|
+
}
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
# Add your nodes and edges here
|
|
466
|
+
dot.node('node1', 'Label 1')
|
|
467
|
+
dot.node('node2', 'Label 2')
|
|
468
|
+
dot.edge('node1', 'node2')
|
|
469
|
+
|
|
470
|
+
# Render to multiple formats
|
|
471
|
+
output_path = f'{output_dir}/{diagram_name}'
|
|
472
|
+
dot.render(output_path, cleanup=True) # PDF
|
|
473
|
+
dot.format = 'svg'
|
|
474
|
+
dot.render(output_path, cleanup=True) # SVG
|
|
475
|
+
dot.format = 'eps'
|
|
476
|
+
dot.render(output_path, cleanup=True) # EPS
|
|
477
|
+
|
|
478
|
+
print(f"✓ Diagram saved: {output_path}.{{pdf,svg,eps}}")
|
|
479
|
+
return f"{output_path}.pdf"
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Step 3: Add Nodes with Clear Labels
|
|
483
|
+
|
|
484
|
+
**Best practices:**
|
|
485
|
+
- Use descriptive node IDs: `'encoder_layer1'` not `'n1'`
|
|
486
|
+
- Use `\n` for multi-line labels
|
|
487
|
+
- Use fill colors to group related components
|
|
488
|
+
- Keep labels concise (3-5 words max per line)
|
|
489
|
+
|
|
490
|
+
```python
|
|
491
|
+
# Good node definitions
|
|
492
|
+
dot.node('input_layer', 'Input Layer\n(512 dims)', fillcolor='#E8F4F8')
|
|
493
|
+
dot.node('attention', 'Multi-Head\nAttention', fillcolor='#B3D9E6')
|
|
494
|
+
dot.node('output', 'Output', fillcolor='#C8E6C9')
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Step 4: Connect Nodes with Edges
|
|
498
|
+
|
|
499
|
+
**Edge types:**
|
|
500
|
+
```python
|
|
501
|
+
# Standard arrow
|
|
502
|
+
dot.edge('node1', 'node2')
|
|
503
|
+
|
|
504
|
+
# Dashed line (for information flow)
|
|
505
|
+
dot.edge('encoder', 'decoder', style='dashed')
|
|
506
|
+
|
|
507
|
+
# Bidirectional
|
|
508
|
+
dot.edge('node1', 'node2', dir='both')
|
|
509
|
+
|
|
510
|
+
# With label
|
|
511
|
+
dot.edge('layer1', 'layer2', label=' ReLU ')
|
|
512
|
+
|
|
513
|
+
# Different color
|
|
514
|
+
dot.edge('input', 'output', color='red', penwidth='2')
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### Step 5: Use Subgraphs for Grouping
|
|
518
|
+
|
|
519
|
+
**For parallel structures (like Encoder/Decoder):**
|
|
520
|
+
```python
|
|
521
|
+
# Encoder cluster
|
|
522
|
+
with dot.subgraph(name='cluster_encoder') as enc:
|
|
523
|
+
enc.attr(label='Encoder', style='rounded', color='blue')
|
|
524
|
+
enc.node('enc1', 'Encoder Layer 1')
|
|
525
|
+
enc.node('enc2', 'Encoder Layer 2')
|
|
526
|
+
enc.edge('enc1', 'enc2')
|
|
527
|
+
|
|
528
|
+
# Decoder cluster
|
|
529
|
+
with dot.subgraph(name='cluster_decoder') as dec:
|
|
530
|
+
dec.attr(label='Decoder', style='rounded', color='red')
|
|
531
|
+
dec.node('dec1', 'Decoder Layer 1')
|
|
532
|
+
dec.node('dec2', 'Decoder Layer 2')
|
|
533
|
+
dec.edge('dec1', 'dec2')
|
|
534
|
+
|
|
535
|
+
# Cross-connection between clusters
|
|
536
|
+
dot.edge('enc2', 'dec1', style='dashed', color='purple')
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Step 6: Render and Verify
|
|
540
|
+
|
|
541
|
+
```python
|
|
542
|
+
# Always render to PDF (for LaTeX) and SVG (for web/slides)
|
|
543
|
+
output_path = f'{output_dir}/{diagram_name}'
|
|
544
|
+
|
|
545
|
+
# PDF for papers
|
|
546
|
+
dot.format = 'pdf'
|
|
547
|
+
dot.render(output_path, cleanup=True)
|
|
548
|
+
|
|
549
|
+
# SVG for posters/slides
|
|
550
|
+
dot.format = 'svg'
|
|
551
|
+
dot.render(output_path, cleanup=True)
|
|
552
|
+
|
|
553
|
+
# EPS for some journals
|
|
554
|
+
dot.format = 'eps'
|
|
555
|
+
dot.render(output_path, cleanup=True)
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
## Common Graphviz Attributes Quick Reference
|
|
559
|
+
|
|
560
|
+
### Graph Attributes (overall layout)
|
|
561
|
+
```python
|
|
562
|
+
graph_attr={
|
|
563
|
+
'rankdir': 'TB', # Direction: TB, BT, LR, RL
|
|
564
|
+
'splines': 'ortho', # Edge style: ortho, curved, line, polyline
|
|
565
|
+
'nodesep': '0.5', # Space between nodes (inches)
|
|
566
|
+
'ranksep': '0.8', # Space between ranks (inches)
|
|
567
|
+
'bgcolor': 'white', # Background color
|
|
568
|
+
'dpi': '300', # Resolution for raster output
|
|
569
|
+
'compound': 'true', # Allow edges between clusters
|
|
570
|
+
'concentrate': 'true' # Merge multiple edges
|
|
571
|
+
}
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
### Node Attributes (boxes/shapes)
|
|
575
|
+
```python
|
|
576
|
+
node_attr={
|
|
577
|
+
'shape': 'box', # box, ellipse, circle, diamond, plaintext
|
|
578
|
+
'style': 'rounded,filled', # rounded, filled, dashed, bold
|
|
579
|
+
'fillcolor': '#E8F4F8', # Fill color (hex or name)
|
|
580
|
+
'color': 'black', # Border color
|
|
581
|
+
'penwidth': '1.5', # Border width
|
|
582
|
+
'fontname': 'Arial', # Font family
|
|
583
|
+
'fontsize': '11', # Font size (points)
|
|
584
|
+
'fontcolor': 'black', # Text color
|
|
585
|
+
'width': '2', # Minimum width (inches)
|
|
586
|
+
'height': '0.5', # Minimum height (inches)
|
|
587
|
+
'margin': '0.2' # Internal padding
|
|
588
|
+
}
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
### Edge Attributes (arrows/connections)
|
|
592
|
+
```python
|
|
593
|
+
edge_attr={
|
|
594
|
+
'color': 'black', # Line color
|
|
595
|
+
'penwidth': '1.5', # Line width
|
|
596
|
+
'style': 'solid', # solid, dashed, dotted, bold
|
|
597
|
+
'arrowsize': '1.0', # Arrow head size
|
|
598
|
+
'dir': 'forward', # forward, back, both, none
|
|
599
|
+
'arrowhead': 'normal' # normal, vee, diamond, dot, none
|
|
600
|
+
}
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
## Colorblind-Safe Palettes
|
|
604
|
+
|
|
605
|
+
Use these color sets to ensure accessibility:
|
|
606
|
+
|
|
607
|
+
### Okabe-Ito Palette (8 colors)
|
|
608
|
+
```python
|
|
609
|
+
OKABE_ITO = {
|
|
610
|
+
'orange': '#E69F00',
|
|
611
|
+
'sky_blue': '#56B4E9',
|
|
612
|
+
'green': '#009E73',
|
|
613
|
+
'yellow': '#F0E442',
|
|
614
|
+
'blue': '#0072B2',
|
|
615
|
+
'vermillion': '#D55E00',
|
|
616
|
+
'purple': '#CC79A7',
|
|
617
|
+
'black': '#000000'
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### Light Backgrounds (for filled nodes)
|
|
622
|
+
```python
|
|
623
|
+
LIGHT_FILLS = {
|
|
624
|
+
'blue': '#E8F4F8',
|
|
625
|
+
'green': '#E8F5E9',
|
|
626
|
+
'orange': '#FFF3E0',
|
|
627
|
+
'purple': '#F3E5F5',
|
|
628
|
+
'red': '#FFEBEE',
|
|
629
|
+
'yellow': '#FFFDE7',
|
|
630
|
+
'gray': '#F5F5F5'
|
|
631
|
+
}
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### 4. Publication Standards
|
|
635
|
+
|
|
636
|
+
All diagrams follow scientific publication best practices:
|
|
637
|
+
|
|
638
|
+
**Vector Format Output**
|
|
639
|
+
- PDF for LaTeX integration (preferred)
|
|
640
|
+
- SVG for web and presentations
|
|
641
|
+
- EPS for legacy publishing systems
|
|
642
|
+
- High-resolution PNG as fallback (300+ DPI)
|
|
643
|
+
|
|
644
|
+
**Colorblind-Friendly Design**
|
|
645
|
+
- Okabe-Ito palette for categorical elements
|
|
646
|
+
- Perceptually uniform colormaps for continuous data
|
|
647
|
+
- Redundant encoding (shapes + colors)
|
|
648
|
+
- Grayscale compatibility verification
|
|
649
|
+
|
|
650
|
+
**Typography Standards**
|
|
651
|
+
- Sans-serif fonts (Arial, Helvetica) for consistency
|
|
652
|
+
- Minimum 7-8 pt text at final print size
|
|
653
|
+
- Clear, readable labels with units
|
|
654
|
+
- Consistent notation throughout
|
|
655
|
+
|
|
656
|
+
**Accessibility**
|
|
657
|
+
- High contrast between elements
|
|
658
|
+
- Adequate line weights (0.5-1 pt minimum)
|
|
659
|
+
- Clear visual hierarchy
|
|
660
|
+
- Descriptive captions and alt text
|
|
661
|
+
|
|
662
|
+
For comprehensive publication guidelines, see `references/best_practices.md`.
|
|
663
|
+
|
|
664
|
+
## Quick Start Examples
|
|
665
|
+
|
|
666
|
+
### Example 1: Simple Flowchart in TikZ
|
|
667
|
+
|
|
668
|
+
```latex
|
|
669
|
+
\documentclass{article}
|
|
670
|
+
\usepackage{tikz}
|
|
671
|
+
\usetikzlibrary{shapes.geometric, arrows.meta}
|
|
672
|
+
|
|
673
|
+
% Load colorblind-safe colors
|
|
674
|
+
\input{tikz_styles.tex}
|
|
675
|
+
|
|
676
|
+
\begin{document}
|
|
677
|
+
|
|
678
|
+
\begin{figure}[h]
|
|
679
|
+
\centering
|
|
680
|
+
\begin{tikzpicture}[
|
|
681
|
+
node distance=2cm,
|
|
682
|
+
process/.style={rectangle, rounded corners, draw=black, thick,
|
|
683
|
+
fill=okabe-blue!20, minimum width=3cm, minimum height=1cm},
|
|
684
|
+
decision/.style={diamond, draw=black, thick, fill=okabe-orange!20,
|
|
685
|
+
minimum width=2cm, aspect=2},
|
|
686
|
+
arrow/.style={-Stealth, thick}
|
|
687
|
+
]
|
|
688
|
+
|
|
689
|
+
% Nodes
|
|
690
|
+
\node (start) [process] {Screen Participants\\(n=500)};
|
|
691
|
+
\node (exclude) [process, below of=start] {Exclude (n=150)\\Age $<$ 18 years};
|
|
692
|
+
\node (randomize) [process, below of=exclude] {Randomize (n=350)};
|
|
693
|
+
\node (treatment) [process, below left=1.5cm and 2cm of randomize]
|
|
694
|
+
{Treatment Group\\(n=175)};
|
|
695
|
+
\node (control) [process, below right=1.5cm and 2cm of randomize]
|
|
696
|
+
{Control Group\\(n=175)};
|
|
697
|
+
\node (analyze) [process, below=3cm of randomize] {Analyze Data};
|
|
698
|
+
|
|
699
|
+
% Arrows
|
|
700
|
+
\draw [arrow] (start) -- (exclude);
|
|
701
|
+
\draw [arrow] (exclude) -- (randomize);
|
|
702
|
+
\draw [arrow] (randomize) -| (treatment);
|
|
703
|
+
\draw [arrow] (randomize) -| (control);
|
|
704
|
+
\draw [arrow] (treatment) |- (analyze);
|
|
705
|
+
\draw [arrow] (control) |- (analyze);
|
|
706
|
+
|
|
707
|
+
\end{tikzpicture}
|
|
708
|
+
\caption{Study participant flow diagram following CONSORT guidelines.}
|
|
709
|
+
\label{fig:consort}
|
|
710
|
+
\end{figure}
|
|
711
|
+
|
|
712
|
+
\end{document}
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### Example 2: Circuit Diagram with Schemdraw
|
|
716
|
+
|
|
717
|
+
```python
|
|
718
|
+
import schemdraw
|
|
719
|
+
import schemdraw.elements as elm
|
|
720
|
+
|
|
721
|
+
# Create drawing with colorblind-safe colors
|
|
722
|
+
d = schemdraw.Drawing()
|
|
723
|
+
|
|
724
|
+
# Voltage source
|
|
725
|
+
d += elm.SourceV().label('$V_s$')
|
|
726
|
+
|
|
727
|
+
# Resistors in series
|
|
728
|
+
d += elm.Resistor().right().label('$R_1$\n1kΩ')
|
|
729
|
+
d += elm.Resistor().label('$R_2$\n2kΩ')
|
|
730
|
+
|
|
731
|
+
# Capacitor
|
|
732
|
+
d += elm.Capacitor().down().label('$C_1$\n10µF')
|
|
733
|
+
|
|
734
|
+
# Close the circuit
|
|
735
|
+
d += elm.Line().left().tox(d.elements[0].start)
|
|
736
|
+
|
|
737
|
+
# Add ground
|
|
738
|
+
d += elm.Ground()
|
|
739
|
+
|
|
740
|
+
# Save as vector graphics
|
|
741
|
+
d.save('circuit_diagram.svg')
|
|
742
|
+
d.save('circuit_diagram.pdf')
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
### Example 3: Biological Pathway with Python
|
|
746
|
+
|
|
747
|
+
```python
|
|
748
|
+
import matplotlib.pyplot as plt
|
|
749
|
+
import matplotlib.patches as mpatches
|
|
750
|
+
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
|
|
751
|
+
|
|
752
|
+
# Okabe-Ito colorblind-safe palette
|
|
753
|
+
colors = {
|
|
754
|
+
'protein': '#56B4E9', # Blue
|
|
755
|
+
'gene': '#009E73', # Green
|
|
756
|
+
'process': '#F0E442', # Yellow
|
|
757
|
+
'inhibition': '#D55E00' # Orange
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
fig, ax = plt.subplots(figsize=(8, 6))
|
|
761
|
+
|
|
762
|
+
# Define proteins as rounded rectangles
|
|
763
|
+
proteins = [
|
|
764
|
+
('Receptor', 1, 5),
|
|
765
|
+
('Kinase A', 3, 5),
|
|
766
|
+
('Kinase B', 5, 5),
|
|
767
|
+
('TF', 7, 5),
|
|
768
|
+
('Gene', 7, 3)
|
|
769
|
+
]
|
|
770
|
+
|
|
771
|
+
for name, x, y in proteins:
|
|
772
|
+
color = colors['gene'] if name == 'Gene' else colors['protein']
|
|
773
|
+
box = FancyBboxPatch((x-0.4, y-0.3), 0.8, 0.6,
|
|
774
|
+
boxstyle="round,pad=0.1",
|
|
775
|
+
facecolor=color, edgecolor='black', linewidth=2)
|
|
776
|
+
ax.add_patch(box)
|
|
777
|
+
ax.text(x, y, name, ha='center', va='center', fontsize=10, fontweight='bold')
|
|
778
|
+
|
|
779
|
+
# Add activation arrows
|
|
780
|
+
arrows = [
|
|
781
|
+
(1.5, 5, 2.5, 5, 'black'), # Receptor -> Kinase A
|
|
782
|
+
(3.5, 5, 4.5, 5, 'black'), # Kinase A -> Kinase B
|
|
783
|
+
(5.5, 5, 6.5, 5, 'black'), # Kinase B -> TF
|
|
784
|
+
(7, 4.7, 7, 3.6, 'black') # TF -> Gene
|
|
785
|
+
]
|
|
786
|
+
|
|
787
|
+
for x1, y1, x2, y2, color in arrows:
|
|
788
|
+
arrow = FancyArrowPatch((x1, y1), (x2, y2),
|
|
789
|
+
arrowstyle='->', mutation_scale=20,
|
|
790
|
+
linewidth=2, color=color)
|
|
791
|
+
ax.add_patch(arrow)
|
|
792
|
+
|
|
793
|
+
# Configure axes
|
|
794
|
+
ax.set_xlim(0, 8.5)
|
|
795
|
+
ax.set_ylim(2, 6)
|
|
796
|
+
ax.set_aspect('equal')
|
|
797
|
+
ax.axis('off')
|
|
798
|
+
|
|
799
|
+
plt.tight_layout()
|
|
800
|
+
plt.savefig('signaling_pathway.pdf', bbox_inches='tight', dpi=300)
|
|
801
|
+
plt.savefig('signaling_pathway.png', bbox_inches='tight', dpi=300)
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
## Production Workflow (From Concept to Publication)
|
|
805
|
+
|
|
806
|
+
Follow this systematic workflow for all diagrams:
|
|
807
|
+
|
|
808
|
+
### Phase 1: Analysis (2 minutes)
|
|
809
|
+
|
|
810
|
+
1. **Identify diagram type** - What are you visualizing?
|
|
811
|
+
- Neural network architecture? → Use graphviz
|
|
812
|
+
- Flowchart (CONSORT, PRISMA)? → Use graphviz
|
|
813
|
+
- Circuit diagram? → Use schemdraw
|
|
814
|
+
- Complex network? → Use networkx + graphviz
|
|
815
|
+
|
|
816
|
+
2. **Determine layout direction**
|
|
817
|
+
- Vertical flow (top-to-bottom)? → `rankdir='TB'`
|
|
818
|
+
- Bottom-up (like Transformer)? → `rankdir='BT'`
|
|
819
|
+
- Left-to-right sequence? → `rankdir='LR'`
|
|
820
|
+
- Right-to-left? → `rankdir='RL'`
|
|
821
|
+
|
|
822
|
+
3. **Identify groupings**
|
|
823
|
+
- Parallel structures (encoder/decoder)? → Use clusters/subgraphs
|
|
824
|
+
- Sequential only? → Simple node chain
|
|
825
|
+
- Cross-connections? → Graphviz handles automatically
|
|
826
|
+
|
|
827
|
+
### Phase 2: Implementation (10-15 minutes)
|
|
828
|
+
|
|
829
|
+
**Standard procedure for 95% of diagrams:**
|
|
830
|
+
|
|
831
|
+
```python
|
|
832
|
+
import graphviz
|
|
833
|
+
from pathlib import Path
|
|
834
|
+
|
|
835
|
+
# 1. Set up output directory
|
|
836
|
+
output_dir = 'figures'
|
|
837
|
+
Path(output_dir).mkdir(exist_ok=True, parents=True)
|
|
838
|
+
|
|
839
|
+
# 2. Create diagram with base template
|
|
840
|
+
dot = graphviz.Digraph(
|
|
841
|
+
'my_diagram',
|
|
842
|
+
format='pdf',
|
|
843
|
+
graph_attr={
|
|
844
|
+
'rankdir': 'TB', # Adjust based on Phase 1
|
|
845
|
+
'splines': 'ortho', # Clean orthogonal edges
|
|
846
|
+
'nodesep': '0.6', # Good default spacing
|
|
847
|
+
'ranksep': '0.8',
|
|
848
|
+
'bgcolor': 'white',
|
|
849
|
+
'dpi': '300'
|
|
850
|
+
},
|
|
851
|
+
node_attr={
|
|
852
|
+
'shape': 'box',
|
|
853
|
+
'style': 'rounded,filled',
|
|
854
|
+
'fillcolor': 'lightgray',
|
|
855
|
+
'fontname': 'Arial',
|
|
856
|
+
'fontsize': '11'
|
|
857
|
+
},
|
|
858
|
+
edge_attr={'color': 'black', 'penwidth': '1.5'}
|
|
859
|
+
)
|
|
860
|
+
|
|
861
|
+
# 3. Add nodes (with descriptive IDs and clear labels)
|
|
862
|
+
dot.node('input', 'Input Layer', fillcolor='#E8F4F8')
|
|
863
|
+
dot.node('hidden', 'Hidden Layer', fillcolor='#B3D9E6')
|
|
864
|
+
dot.node('output', 'Output Layer', fillcolor='#C8E6C9')
|
|
865
|
+
|
|
866
|
+
# 4. Add edges
|
|
867
|
+
dot.edge('input', 'hidden')
|
|
868
|
+
dot.edge('hidden', 'output')
|
|
869
|
+
|
|
870
|
+
# 5. Render to figures/ folder
|
|
871
|
+
output_path = f'{output_dir}/my_diagram'
|
|
872
|
+
dot.render(output_path, cleanup=True) # Creates PDF
|
|
873
|
+
dot.format = 'svg'
|
|
874
|
+
dot.render(output_path, cleanup=True) # Creates SVG
|
|
875
|
+
dot.format = 'eps'
|
|
876
|
+
dot.render(output_path, cleanup=True) # Creates EPS
|
|
877
|
+
|
|
878
|
+
print(f"✓ Saved to: {output_path}.{{pdf,svg,eps}}")
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### Phase 3: Quality Verification (5 minutes)
|
|
882
|
+
|
|
883
|
+
**Automatic checks:**
|
|
884
|
+
```python
|
|
885
|
+
# Convert PDF to PNG for quality checking
|
|
886
|
+
from pdf2image import convert_from_path
|
|
887
|
+
|
|
888
|
+
pages = convert_from_path(f'{output_path}.pdf', dpi=300)
|
|
889
|
+
pages[0].save(f'{output_path}.png')
|
|
890
|
+
|
|
891
|
+
# Run quality checks
|
|
892
|
+
from quality_checker import run_quality_checks
|
|
893
|
+
report = run_quality_checks(f'{output_path}.png')
|
|
894
|
+
|
|
895
|
+
if report['overall_status'] != 'PASS':
|
|
896
|
+
print("⚠️ Issues detected - review quality_reports/")
|
|
897
|
+
# Adjust spacing: increase nodesep or ranksep
|
|
898
|
+
# Adjust colors: check accessibility report
|
|
899
|
+
else:
|
|
900
|
+
print("✓ Quality checks passed!")
|
|
901
|
+
```
|
|
902
|
+
|
|
903
|
+
**Manual verification:**
|
|
904
|
+
1. Open PDF in viewer - check for overlaps
|
|
905
|
+
2. Verify text is readable (zoom to 100%)
|
|
906
|
+
3. Check alignment and spacing looks professional
|
|
907
|
+
4. Ensure colors are distinguishable
|
|
908
|
+
|
|
909
|
+
### Phase 4: LaTeX Integration (2 minutes)
|
|
910
|
+
|
|
911
|
+
**In your LaTeX document:**
|
|
912
|
+
|
|
913
|
+
```latex
|
|
914
|
+
% In preamble
|
|
915
|
+
\usepackage{graphicx}
|
|
916
|
+
|
|
917
|
+
% In document
|
|
918
|
+
\begin{figure}[htbp]
|
|
919
|
+
\centering
|
|
920
|
+
\includegraphics[width=0.8\textwidth]{figures/my_diagram.pdf}
|
|
921
|
+
\caption{Clear, descriptive caption explaining all components and abbreviations.
|
|
922
|
+
Define any non-standard notation used in the diagram.}
|
|
923
|
+
\label{fig:my_diagram}
|
|
924
|
+
\end{figure}
|
|
925
|
+
|
|
926
|
+
% Reference in text
|
|
927
|
+
As shown in Figure~\ref{fig:my_diagram}, the architecture consists of...
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
**For posters (beamer):**
|
|
931
|
+
```latex
|
|
932
|
+
\begin{frame}{Architecture}
|
|
933
|
+
\begin{center}
|
|
934
|
+
\includegraphics[width=0.9\textwidth]{figures/my_diagram.pdf}
|
|
935
|
+
\end{center}
|
|
936
|
+
\end{frame}
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
### Phase 5: Version Control (1 minute)
|
|
940
|
+
|
|
941
|
+
**Always commit:**
|
|
942
|
+
1. Python source code (`create_my_diagram.py`)
|
|
943
|
+
2. Generated outputs (`figures/my_diagram.{pdf,svg,eps}`)
|
|
944
|
+
3. Quality reports (`my_diagram_quality_reports/`)
|
|
945
|
+
|
|
946
|
+
```bash
|
|
947
|
+
git add create_my_diagram.py
|
|
948
|
+
git add figures/my_diagram.*
|
|
949
|
+
git add my_diagram_quality_reports/
|
|
950
|
+
git commit -m "Add architecture diagram with quality verification"
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
## Troubleshooting Common Issues
|
|
954
|
+
|
|
955
|
+
### Graphviz-Specific Problems
|
|
956
|
+
|
|
957
|
+
**Problem:** Nodes overlap or are too close
|
|
958
|
+
```python
|
|
959
|
+
# Solution: Increase spacing
|
|
960
|
+
graph_attr={
|
|
961
|
+
'nodesep': '1.0', # Increase from default 0.6
|
|
962
|
+
'ranksep': '1.2' # Increase from default 0.8
|
|
963
|
+
}
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
**Problem:** Edges cross in confusing ways
|
|
967
|
+
```python
|
|
968
|
+
# Solution 1: Use orthogonal splines
|
|
969
|
+
graph_attr={'splines': 'ortho'}
|
|
970
|
+
|
|
971
|
+
# Solution 2: Adjust rank direction
|
|
972
|
+
graph_attr={'rankdir': 'LR'} # Try different directions
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
**Problem:** Labels are cut off or too small
|
|
976
|
+
```python
|
|
977
|
+
# Solution: Adjust node size and font
|
|
978
|
+
node_attr={
|
|
979
|
+
'fontsize': '12', # Increase from 11
|
|
980
|
+
'margin': '0.3', # More internal padding
|
|
981
|
+
'width': '2.5', # Wider boxes
|
|
982
|
+
'height': '0.6' # Taller boxes
|
|
983
|
+
}
|
|
984
|
+
```
|
|
985
|
+
|
|
986
|
+
**Problem:** Clusters/subgraphs not appearing
|
|
987
|
+
```python
|
|
988
|
+
# Solution: Cluster names MUST start with 'cluster_'
|
|
989
|
+
with dot.subgraph(name='cluster_encoder') as enc: # ✓ Correct
|
|
990
|
+
enc.attr(label='Encoder')
|
|
991
|
+
|
|
992
|
+
with dot.subgraph(name='encoder') as enc: # ✗ Won't show as cluster
|
|
993
|
+
enc.attr(label='Encoder')
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
**Problem:** Cross-cluster edges not working
|
|
997
|
+
```python
|
|
998
|
+
# Solution: Enable compound edges
|
|
999
|
+
dot.attr(compound='true')
|
|
1000
|
+
|
|
1001
|
+
# Then use lhead/ltail for cluster connections
|
|
1002
|
+
dot.edge('node1', 'node2', lhead='cluster_decoder')
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
**Problem:** Graphviz not found error
|
|
1006
|
+
```bash
|
|
1007
|
+
# Solution: Install graphviz binary (not just Python package)
|
|
1008
|
+
# macOS
|
|
1009
|
+
brew install graphviz
|
|
1010
|
+
|
|
1011
|
+
# Ubuntu
|
|
1012
|
+
sudo apt-get install graphviz
|
|
1013
|
+
|
|
1014
|
+
# Then install Python bindings
|
|
1015
|
+
pip install graphviz
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
### Visual Quality Issues
|
|
1019
|
+
|
|
1020
|
+
**Problem:** Colors not colorblind-safe
|
|
1021
|
+
```python
|
|
1022
|
+
# Solution: Use Okabe-Ito palette
|
|
1023
|
+
COLORS = {
|
|
1024
|
+
'blue': '#56B4E9',
|
|
1025
|
+
'green': '#009E73',
|
|
1026
|
+
'orange': '#E69F00',
|
|
1027
|
+
'purple': '#CC79A7'
|
|
1028
|
+
}
|
|
1029
|
+
dot.node('n1', 'Node', fillcolor=COLORS['blue'])
|
|
1030
|
+
```
|
|
1031
|
+
|
|
1032
|
+
**Problem:** Text too small when printed
|
|
1033
|
+
```python
|
|
1034
|
+
# Solution: Increase font size and DPI
|
|
1035
|
+
node_attr={'fontsize': '12'} # Minimum 11-12 for print
|
|
1036
|
+
graph_attr={'dpi': '300'} # Publication quality
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
**Problem:** PDF too large
|
|
1040
|
+
```python
|
|
1041
|
+
# Solution 1: Use simpler edge routing
|
|
1042
|
+
graph_attr={'splines': 'line'} # Simpler than 'ortho'
|
|
1043
|
+
|
|
1044
|
+
# Solution 2: Reduce DPI for drafts
|
|
1045
|
+
graph_attr={'dpi': '150'} # For drafts only
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
### Workflow Issues
|
|
1049
|
+
|
|
1050
|
+
**Problem:** Need to regenerate diagram after changes
|
|
1051
|
+
```python
|
|
1052
|
+
# Solution: Make diagram generation a function
|
|
1053
|
+
def create_diagram(params):
|
|
1054
|
+
# ... diagram code ...
|
|
1055
|
+
return output_path
|
|
1056
|
+
|
|
1057
|
+
# Easy to regenerate with different parameters
|
|
1058
|
+
create_diagram({'nodesep': '0.8', 'ranksep': '1.0'})
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
**Problem:** Diagram doesn't match paper figures style
|
|
1062
|
+
```python
|
|
1063
|
+
# Solution: Create a reusable style configuration
|
|
1064
|
+
PAPER_STYLE = {
|
|
1065
|
+
'graph_attr': {
|
|
1066
|
+
'rankdir': 'TB',
|
|
1067
|
+
'bgcolor': 'white',
|
|
1068
|
+
'dpi': '300'
|
|
1069
|
+
},
|
|
1070
|
+
'node_attr': {
|
|
1071
|
+
'fontname': 'Arial',
|
|
1072
|
+
'fontsize': '11',
|
|
1073
|
+
'style': 'rounded,filled',
|
|
1074
|
+
'fillcolor': '#E8F4F8'
|
|
1075
|
+
},
|
|
1076
|
+
'edge_attr': {
|
|
1077
|
+
'color': 'black',
|
|
1078
|
+
'penwidth': '1.5'
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
# Use for all diagrams
|
|
1083
|
+
dot = graphviz.Digraph(**PAPER_STYLE)
|
|
1084
|
+
```
|
|
1085
|
+
|
|
1086
|
+
## Visual Verification and Quality Control
|
|
1087
|
+
|
|
1088
|
+
All diagrams undergo automated visual quality checks to prevent overlaps, ensure readability, and verify accessibility. This multi-stage verification process uses computer vision techniques to detect common issues.
|
|
1089
|
+
|
|
1090
|
+
### Stage 1: Overlap Detection
|
|
1091
|
+
|
|
1092
|
+
Automatically detect overlapping elements that reduce clarity:
|
|
1093
|
+
|
|
1094
|
+
```python
|
|
1095
|
+
import numpy as np
|
|
1096
|
+
from PIL import Image
|
|
1097
|
+
import json
|
|
1098
|
+
from pathlib import Path
|
|
1099
|
+
|
|
1100
|
+
def detect_overlaps(image_path, threshold=0.95):
|
|
1101
|
+
"""
|
|
1102
|
+
Detect potential overlapping regions in a diagram.
|
|
1103
|
+
|
|
1104
|
+
Args:
|
|
1105
|
+
image_path: Path to the rendered diagram (PNG/PDF)
|
|
1106
|
+
threshold: Similarity threshold for detecting overlaps (0-1)
|
|
1107
|
+
|
|
1108
|
+
Returns:
|
|
1109
|
+
dict: Overlap report with locations and severity
|
|
1110
|
+
"""
|
|
1111
|
+
# Load image
|
|
1112
|
+
img = Image.open(image_path).convert('RGB')
|
|
1113
|
+
img_array = np.array(img)
|
|
1114
|
+
|
|
1115
|
+
# Detect dense regions (potential overlaps)
|
|
1116
|
+
gray = np.mean(img_array, axis=2)
|
|
1117
|
+
|
|
1118
|
+
# Edge detection to find boundaries
|
|
1119
|
+
from scipy.ndimage import sobel
|
|
1120
|
+
edges_x = sobel(gray, axis=0)
|
|
1121
|
+
edges_y = sobel(gray, axis=1)
|
|
1122
|
+
edge_magnitude = np.hypot(edges_x, edges_y)
|
|
1123
|
+
|
|
1124
|
+
# Find regions with high edge density (overlaps)
|
|
1125
|
+
from scipy.ndimage import label, find_objects
|
|
1126
|
+
binary_edges = edge_magnitude > np.percentile(edge_magnitude, 85)
|
|
1127
|
+
labeled_regions, num_features = label(binary_edges)
|
|
1128
|
+
|
|
1129
|
+
overlaps = []
|
|
1130
|
+
slices = find_objects(labeled_regions)
|
|
1131
|
+
|
|
1132
|
+
for i, slice_obj in enumerate(slices):
|
|
1133
|
+
if slice_obj is not None:
|
|
1134
|
+
region = edge_magnitude[slice_obj]
|
|
1135
|
+
density = np.mean(region)
|
|
1136
|
+
|
|
1137
|
+
# High density suggests potential overlap
|
|
1138
|
+
if density > threshold * np.max(edge_magnitude):
|
|
1139
|
+
y_center = (slice_obj[0].start + slice_obj[0].stop) // 2
|
|
1140
|
+
x_center = (slice_obj[1].start + slice_obj[1].stop) // 2
|
|
1141
|
+
|
|
1142
|
+
overlaps.append({
|
|
1143
|
+
'region_id': i + 1,
|
|
1144
|
+
'position': (x_center, y_center),
|
|
1145
|
+
'density': float(density),
|
|
1146
|
+
'severity': 'high' if density > 0.98 * np.max(edge_magnitude) else 'medium'
|
|
1147
|
+
})
|
|
1148
|
+
|
|
1149
|
+
report = {
|
|
1150
|
+
'image': str(image_path),
|
|
1151
|
+
'overlaps_detected': len(overlaps),
|
|
1152
|
+
'overlap_regions': overlaps,
|
|
1153
|
+
'status': 'PASS' if len(overlaps) == 0 else 'WARNING'
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
return report
|
|
1157
|
+
|
|
1158
|
+
def save_overlap_report(report, output_path='overlap_report.json'):
|
|
1159
|
+
"""Save overlap detection report to JSON."""
|
|
1160
|
+
with open(output_path, 'w') as f:
|
|
1161
|
+
json.dump(report, indent=2, fp=f)
|
|
1162
|
+
|
|
1163
|
+
print(f"Overlap Report: {report['status']}")
|
|
1164
|
+
print(f" - Overlaps detected: {report['overlaps_detected']}")
|
|
1165
|
+
if report['overlap_regions']:
|
|
1166
|
+
print(" - Regions requiring review:")
|
|
1167
|
+
for region in report['overlap_regions']:
|
|
1168
|
+
print(f" * Region {region['region_id']}: "
|
|
1169
|
+
f"Position {region['position']}, Severity: {region['severity']}")
|
|
1170
|
+
```
|
|
1171
|
+
|
|
1172
|
+
### Stage 2: Contrast and Accessibility Verification
|
|
1173
|
+
|
|
1174
|
+
Ensure diagrams meet accessibility standards for colorblind readers:
|
|
1175
|
+
|
|
1176
|
+
```python
|
|
1177
|
+
def verify_accessibility(image_path):
|
|
1178
|
+
"""
|
|
1179
|
+
Verify diagram meets accessibility standards.
|
|
1180
|
+
|
|
1181
|
+
Checks:
|
|
1182
|
+
- Sufficient contrast ratios
|
|
1183
|
+
- Grayscale readability
|
|
1184
|
+
- Text size adequacy
|
|
1185
|
+
"""
|
|
1186
|
+
from PIL import ImageFilter, ImageStat
|
|
1187
|
+
|
|
1188
|
+
img = Image.open(image_path).convert('RGB')
|
|
1189
|
+
|
|
1190
|
+
# Test 1: Grayscale conversion
|
|
1191
|
+
grayscale = img.convert('L')
|
|
1192
|
+
gray_stat = ImageStat.Stat(grayscale)
|
|
1193
|
+
|
|
1194
|
+
# Calculate contrast (std dev of grayscale)
|
|
1195
|
+
contrast = gray_stat.stddev[0]
|
|
1196
|
+
min_contrast = 30 # Minimum standard deviation for good contrast
|
|
1197
|
+
|
|
1198
|
+
# Test 2: Color distribution
|
|
1199
|
+
rgb_array = np.array(img)
|
|
1200
|
+
unique_colors = len(np.unique(rgb_array.reshape(-1, 3), axis=0))
|
|
1201
|
+
|
|
1202
|
+
# Test 3: Simulate common color blindness (deuteranopia)
|
|
1203
|
+
def simulate_colorblind(img_array):
|
|
1204
|
+
# Simplified deuteranopia simulation
|
|
1205
|
+
colorblind = img_array.copy().astype(float)
|
|
1206
|
+
colorblind[:, :, 0] = 0.625 * img_array[:, :, 0] + 0.375 * img_array[:, :, 1]
|
|
1207
|
+
colorblind[:, :, 1] = 0.7 * img_array[:, :, 1] + 0.3 * img_array[:, :, 0]
|
|
1208
|
+
return colorblind.astype(np.uint8)
|
|
1209
|
+
|
|
1210
|
+
colorblind_img = simulate_colorblind(np.array(img))
|
|
1211
|
+
cb_image = Image.fromarray(colorblind_img)
|
|
1212
|
+
cb_gray = cb_image.convert('L')
|
|
1213
|
+
cb_stat = ImageStat.Stat(cb_gray)
|
|
1214
|
+
cb_contrast = cb_stat.stddev[0]
|
|
1215
|
+
|
|
1216
|
+
report = {
|
|
1217
|
+
'image': str(image_path),
|
|
1218
|
+
'checks': {
|
|
1219
|
+
'grayscale_contrast': {
|
|
1220
|
+
'value': contrast,
|
|
1221
|
+
'threshold': min_contrast,
|
|
1222
|
+
'status': 'PASS' if contrast >= min_contrast else 'FAIL'
|
|
1223
|
+
},
|
|
1224
|
+
'colorblind_contrast': {
|
|
1225
|
+
'value': cb_contrast,
|
|
1226
|
+
'threshold': min_contrast * 0.8,
|
|
1227
|
+
'status': 'PASS' if cb_contrast >= min_contrast * 0.8 else 'FAIL'
|
|
1228
|
+
},
|
|
1229
|
+
'color_diversity': {
|
|
1230
|
+
'unique_colors': unique_colors,
|
|
1231
|
+
'status': 'INFO'
|
|
1232
|
+
}
|
|
1233
|
+
},
|
|
1234
|
+
'overall_status': 'PASS' if (contrast >= min_contrast and
|
|
1235
|
+
cb_contrast >= min_contrast * 0.8) else 'FAIL'
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
return report
|
|
1239
|
+
|
|
1240
|
+
def save_accessibility_report(report, output_path='accessibility_report.json'):
|
|
1241
|
+
"""Save accessibility report to JSON."""
|
|
1242
|
+
with open(output_path, 'w') as f:
|
|
1243
|
+
json.dump(report, indent=2, fp=f)
|
|
1244
|
+
|
|
1245
|
+
print(f"Accessibility Report: {report['overall_status']}")
|
|
1246
|
+
for check_name, check_data in report['checks'].items():
|
|
1247
|
+
print(f" - {check_name}: {check_data['status']}")
|
|
1248
|
+
if 'value' in check_data and 'threshold' in check_data:
|
|
1249
|
+
print(f" Value: {check_data['value']:.2f}, Threshold: {check_data['threshold']:.2f}")
|
|
1250
|
+
```
|
|
1251
|
+
|
|
1252
|
+
### Stage 3: Text Size and Resolution Validation
|
|
1253
|
+
|
|
1254
|
+
Verify text is readable at publication size:
|
|
1255
|
+
|
|
1256
|
+
```python
|
|
1257
|
+
def validate_resolution(image_path, target_dpi=300, min_text_size_pt=7):
|
|
1258
|
+
"""
|
|
1259
|
+
Validate image resolution and estimated text size.
|
|
1260
|
+
|
|
1261
|
+
Args:
|
|
1262
|
+
image_path: Path to diagram image
|
|
1263
|
+
target_dpi: Target DPI for publication (default 300)
|
|
1264
|
+
min_text_size_pt: Minimum acceptable text size in points
|
|
1265
|
+
"""
|
|
1266
|
+
from PIL import Image
|
|
1267
|
+
import pytesseract
|
|
1268
|
+
|
|
1269
|
+
img = Image.open(image_path)
|
|
1270
|
+
|
|
1271
|
+
# Check DPI
|
|
1272
|
+
dpi = img.info.get('dpi', (72, 72))
|
|
1273
|
+
actual_dpi = dpi[0] if isinstance(dpi, tuple) else dpi
|
|
1274
|
+
|
|
1275
|
+
# Estimate text size (simplified - assumes text detection)
|
|
1276
|
+
# For production, use OCR or PDF text extraction
|
|
1277
|
+
width, height = img.size
|
|
1278
|
+
dpi_ratio = actual_dpi / 72 # Convert to screen pixels
|
|
1279
|
+
|
|
1280
|
+
# Calculate physical size in inches
|
|
1281
|
+
width_inches = width / actual_dpi if actual_dpi > 0 else width / 72
|
|
1282
|
+
height_inches = height / actual_dpi if actual_dpi > 0 else height / 72
|
|
1283
|
+
|
|
1284
|
+
report = {
|
|
1285
|
+
'image': str(image_path),
|
|
1286
|
+
'resolution': {
|
|
1287
|
+
'dpi': actual_dpi,
|
|
1288
|
+
'target_dpi': target_dpi,
|
|
1289
|
+
'status': 'PASS' if actual_dpi >= target_dpi else 'WARNING'
|
|
1290
|
+
},
|
|
1291
|
+
'dimensions': {
|
|
1292
|
+
'pixels': {'width': width, 'height': height},
|
|
1293
|
+
'inches': {'width': round(width_inches, 2),
|
|
1294
|
+
'height': round(height_inches, 2)}
|
|
1295
|
+
},
|
|
1296
|
+
'recommendations': []
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
if actual_dpi < target_dpi:
|
|
1300
|
+
report['recommendations'].append(
|
|
1301
|
+
f"Increase resolution to {target_dpi} DPI for publication quality"
|
|
1302
|
+
)
|
|
1303
|
+
|
|
1304
|
+
if width_inches > 7:
|
|
1305
|
+
report['recommendations'].append(
|
|
1306
|
+
"Image width exceeds typical single-column width (7 inches)"
|
|
1307
|
+
)
|
|
1308
|
+
|
|
1309
|
+
return report
|
|
1310
|
+
```
|
|
1311
|
+
|
|
1312
|
+
### Stage 4: Comprehensive Quality Check Pipeline
|
|
1313
|
+
|
|
1314
|
+
Run all verification stages in sequence:
|
|
1315
|
+
|
|
1316
|
+
```python
|
|
1317
|
+
def run_quality_checks(image_path, output_dir='quality_reports'):
|
|
1318
|
+
"""
|
|
1319
|
+
Run comprehensive quality checks on diagram.
|
|
1320
|
+
|
|
1321
|
+
Args:
|
|
1322
|
+
image_path: Path to diagram to verify
|
|
1323
|
+
output_dir: Directory to save reports
|
|
1324
|
+
|
|
1325
|
+
Returns:
|
|
1326
|
+
dict: Comprehensive quality report
|
|
1327
|
+
"""
|
|
1328
|
+
import os
|
|
1329
|
+
from datetime import datetime
|
|
1330
|
+
|
|
1331
|
+
Path(output_dir).mkdir(exist_ok=True)
|
|
1332
|
+
|
|
1333
|
+
print(f"Running quality checks on: {image_path}")
|
|
1334
|
+
print("=" * 60)
|
|
1335
|
+
|
|
1336
|
+
# Stage 1: Overlap Detection
|
|
1337
|
+
print("\n[Stage 1/4] Detecting overlaps...")
|
|
1338
|
+
overlap_report = detect_overlaps(image_path)
|
|
1339
|
+
save_overlap_report(
|
|
1340
|
+
overlap_report,
|
|
1341
|
+
f"{output_dir}/overlap_report.json"
|
|
1342
|
+
)
|
|
1343
|
+
|
|
1344
|
+
# Stage 2: Accessibility
|
|
1345
|
+
print("\n[Stage 2/4] Verifying accessibility...")
|
|
1346
|
+
accessibility_report = verify_accessibility(image_path)
|
|
1347
|
+
save_accessibility_report(
|
|
1348
|
+
accessibility_report,
|
|
1349
|
+
f"{output_dir}/accessibility_report.json"
|
|
1350
|
+
)
|
|
1351
|
+
|
|
1352
|
+
# Stage 3: Resolution
|
|
1353
|
+
print("\n[Stage 3/4] Validating resolution...")
|
|
1354
|
+
resolution_report = validate_resolution(image_path)
|
|
1355
|
+
with open(f"{output_dir}/resolution_report.json", 'w') as f:
|
|
1356
|
+
json.dump(resolution_report, f, indent=2)
|
|
1357
|
+
|
|
1358
|
+
# Stage 4: Generate visual report
|
|
1359
|
+
print("\n[Stage 4/4] Generating visual report...")
|
|
1360
|
+
create_visual_report(
|
|
1361
|
+
image_path,
|
|
1362
|
+
overlap_report,
|
|
1363
|
+
accessibility_report,
|
|
1364
|
+
f"{output_dir}/visual_report.png"
|
|
1365
|
+
)
|
|
1366
|
+
|
|
1367
|
+
# Comprehensive summary
|
|
1368
|
+
all_pass = (
|
|
1369
|
+
overlap_report['status'] != 'FAIL' and
|
|
1370
|
+
accessibility_report['overall_status'] != 'FAIL' and
|
|
1371
|
+
resolution_report['resolution']['status'] != 'FAIL'
|
|
1372
|
+
)
|
|
1373
|
+
|
|
1374
|
+
summary = {
|
|
1375
|
+
'timestamp': datetime.now().isoformat(),
|
|
1376
|
+
'image': str(image_path),
|
|
1377
|
+
'overall_status': 'PASS' if all_pass else 'NEEDS REVIEW',
|
|
1378
|
+
'stage_results': {
|
|
1379
|
+
'overlap_detection': overlap_report['status'],
|
|
1380
|
+
'accessibility': accessibility_report['overall_status'],
|
|
1381
|
+
'resolution': resolution_report['resolution']['status']
|
|
1382
|
+
},
|
|
1383
|
+
'reports_saved_to': output_dir
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
with open(f"{output_dir}/summary.json", 'w') as f:
|
|
1387
|
+
json.dump(summary, f, indent=2)
|
|
1388
|
+
|
|
1389
|
+
print("\n" + "=" * 60)
|
|
1390
|
+
print(f"OVERALL STATUS: {summary['overall_status']}")
|
|
1391
|
+
print(f"Reports saved to: {output_dir}/")
|
|
1392
|
+
print("=" * 60)
|
|
1393
|
+
|
|
1394
|
+
return summary
|
|
1395
|
+
|
|
1396
|
+
def create_visual_report(image_path, overlap_report, accessibility_report, output_path):
|
|
1397
|
+
"""Create visual report with annotations."""
|
|
1398
|
+
import matplotlib.pyplot as plt
|
|
1399
|
+
from matplotlib.patches import Circle
|
|
1400
|
+
|
|
1401
|
+
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
|
|
1402
|
+
|
|
1403
|
+
# Load original image
|
|
1404
|
+
img = Image.open(image_path)
|
|
1405
|
+
|
|
1406
|
+
# Panel 1: Original with overlap markers
|
|
1407
|
+
axes[0].imshow(img)
|
|
1408
|
+
axes[0].set_title('Overlap Detection', fontsize=12, fontweight='bold')
|
|
1409
|
+
if overlap_report['overlap_regions']:
|
|
1410
|
+
for region in overlap_report['overlap_regions']:
|
|
1411
|
+
x, y = region['position']
|
|
1412
|
+
color = 'red' if region['severity'] == 'high' else 'orange'
|
|
1413
|
+
circle = Circle((x, y), 20, color=color, fill=False, linewidth=2)
|
|
1414
|
+
axes[0].add_patch(circle)
|
|
1415
|
+
axes[0].axis('off')
|
|
1416
|
+
axes[0].text(0.02, 0.98, f"Status: {overlap_report['status']}",
|
|
1417
|
+
transform=axes[0].transAxes, fontsize=10,
|
|
1418
|
+
verticalalignment='top', bbox=dict(boxstyle='round',
|
|
1419
|
+
facecolor='wheat', alpha=0.5))
|
|
1420
|
+
|
|
1421
|
+
# Panel 2: Grayscale version
|
|
1422
|
+
gray_img = img.convert('L')
|
|
1423
|
+
axes[1].imshow(gray_img, cmap='gray')
|
|
1424
|
+
axes[1].set_title('Grayscale Preview', fontsize=12, fontweight='bold')
|
|
1425
|
+
axes[1].axis('off')
|
|
1426
|
+
gray_status = accessibility_report['checks']['grayscale_contrast']['status']
|
|
1427
|
+
axes[1].text(0.02, 0.98, f"Status: {gray_status}",
|
|
1428
|
+
transform=axes[1].transAxes, fontsize=10,
|
|
1429
|
+
verticalalignment='top', bbox=dict(boxstyle='round',
|
|
1430
|
+
facecolor='wheat', alpha=0.5))
|
|
1431
|
+
|
|
1432
|
+
# Panel 3: Colorblind simulation
|
|
1433
|
+
img_array = np.array(img)
|
|
1434
|
+
colorblind = img_array.copy().astype(float)
|
|
1435
|
+
colorblind[:, :, 0] = 0.625 * img_array[:, :, 0] + 0.375 * img_array[:, :, 1]
|
|
1436
|
+
colorblind[:, :, 1] = 0.7 * img_array[:, :, 1] + 0.3 * img_array[:, :, 0]
|
|
1437
|
+
axes[2].imshow(colorblind.astype(np.uint8))
|
|
1438
|
+
axes[2].set_title('Colorblind Simulation', fontsize=12, fontweight='bold')
|
|
1439
|
+
axes[2].axis('off')
|
|
1440
|
+
cb_status = accessibility_report['checks']['colorblind_contrast']['status']
|
|
1441
|
+
axes[2].text(0.02, 0.98, f"Status: {cb_status}",
|
|
1442
|
+
transform=axes[2].transAxes, fontsize=10,
|
|
1443
|
+
verticalalignment='top', bbox=dict(boxstyle='round',
|
|
1444
|
+
facecolor='wheat', alpha=0.5))
|
|
1445
|
+
|
|
1446
|
+
plt.tight_layout()
|
|
1447
|
+
plt.savefig(output_path, dpi=150, bbox_inches='tight')
|
|
1448
|
+
print(f"Visual report saved: {output_path}")
|
|
1449
|
+
plt.close()
|
|
1450
|
+
```
|
|
1451
|
+
|
|
1452
|
+
### Usage Example: Complete Workflow with Verification
|
|
1453
|
+
|
|
1454
|
+
Here's how to create a diagram with full quality verification:
|
|
1455
|
+
|
|
1456
|
+
```python
|
|
1457
|
+
import matplotlib.pyplot as plt
|
|
1458
|
+
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
|
|
1459
|
+
|
|
1460
|
+
# Step 1: Create diagram
|
|
1461
|
+
def create_flowchart_with_verification(output_base='flowchart'):
|
|
1462
|
+
"""Create flowchart with automated quality checks."""
|
|
1463
|
+
|
|
1464
|
+
# Okabe-Ito colorblind-safe palette
|
|
1465
|
+
colors = {
|
|
1466
|
+
'process': '#56B4E9', # Blue
|
|
1467
|
+
'decision': '#E69F00', # Orange
|
|
1468
|
+
'data': '#009E73', # Green
|
|
1469
|
+
'terminal': '#CC79A7' # Purple
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
fig, ax = plt.subplots(figsize=(8, 10))
|
|
1473
|
+
|
|
1474
|
+
# Define flowchart elements with careful spacing
|
|
1475
|
+
elements = [
|
|
1476
|
+
('Start', 4, 9, 'terminal'),
|
|
1477
|
+
('Input Data', 4, 7.5, 'data'),
|
|
1478
|
+
('Process A', 4, 6, 'process'),
|
|
1479
|
+
('Decision?', 4, 4.5, 'decision'),
|
|
1480
|
+
('Process B1', 2, 3, 'process'),
|
|
1481
|
+
('Process B2', 6, 3, 'process'),
|
|
1482
|
+
('Output', 4, 1.5, 'data'),
|
|
1483
|
+
('End', 4, 0, 'terminal')
|
|
1484
|
+
]
|
|
1485
|
+
|
|
1486
|
+
# Draw boxes with adequate spacing
|
|
1487
|
+
box_positions = {}
|
|
1488
|
+
for label, x, y, element_type in elements:
|
|
1489
|
+
color = colors[element_type]
|
|
1490
|
+
width, height = (1.2, 0.6) if element_type != 'decision' else (1.5, 1.0)
|
|
1491
|
+
|
|
1492
|
+
box = FancyBboxPatch(
|
|
1493
|
+
(x - width/2, y - height/2), width, height,
|
|
1494
|
+
boxstyle="round,pad=0.1" if element_type != 'decision' else "round,pad=0.05",
|
|
1495
|
+
facecolor=color, edgecolor='black', linewidth=2
|
|
1496
|
+
)
|
|
1497
|
+
ax.add_patch(box)
|
|
1498
|
+
ax.text(x, y, label, ha='center', va='center',
|
|
1499
|
+
fontsize=10, fontweight='bold')
|
|
1500
|
+
box_positions[label] = (x, y)
|
|
1501
|
+
|
|
1502
|
+
# Draw arrows with proper spacing
|
|
1503
|
+
arrows = [
|
|
1504
|
+
('Start', 'Input Data'),
|
|
1505
|
+
('Input Data', 'Process A'),
|
|
1506
|
+
('Process A', 'Decision?'),
|
|
1507
|
+
('Decision?', 'Process B1'),
|
|
1508
|
+
('Decision?', 'Process B2'),
|
|
1509
|
+
('Process B1', 'Output'),
|
|
1510
|
+
('Process B2', 'Output'),
|
|
1511
|
+
('Output', 'End')
|
|
1512
|
+
]
|
|
1513
|
+
|
|
1514
|
+
for start, end in arrows:
|
|
1515
|
+
x1, y1 = box_positions[start]
|
|
1516
|
+
x2, y2 = box_positions[end]
|
|
1517
|
+
|
|
1518
|
+
# Calculate arrow start/end points to avoid overlap
|
|
1519
|
+
if x1 == x2: # Vertical arrow
|
|
1520
|
+
y1_adj = y1 - 0.3 if y2 < y1 else y1 + 0.3
|
|
1521
|
+
y2_adj = y2 + 0.3 if y2 < y1 else y2 - 0.3
|
|
1522
|
+
arrow = FancyArrowPatch(
|
|
1523
|
+
(x1, y1_adj), (x2, y2_adj),
|
|
1524
|
+
arrowstyle='->', mutation_scale=20, linewidth=2, color='black'
|
|
1525
|
+
)
|
|
1526
|
+
else: # Diagonal arrow
|
|
1527
|
+
arrow = FancyArrowPatch(
|
|
1528
|
+
(x1, y1 - 0.5), (x2, y2 + 0.3),
|
|
1529
|
+
arrowstyle='->', mutation_scale=20, linewidth=2, color='black'
|
|
1530
|
+
)
|
|
1531
|
+
ax.add_patch(arrow)
|
|
1532
|
+
|
|
1533
|
+
ax.set_xlim(0, 8)
|
|
1534
|
+
ax.set_ylim(-0.5, 9.5)
|
|
1535
|
+
ax.set_aspect('equal')
|
|
1536
|
+
ax.axis('off')
|
|
1537
|
+
|
|
1538
|
+
plt.tight_layout()
|
|
1539
|
+
|
|
1540
|
+
# Save in multiple formats
|
|
1541
|
+
plt.savefig(f'{output_base}.pdf', bbox_inches='tight', dpi=300)
|
|
1542
|
+
plt.savefig(f'{output_base}.png', bbox_inches='tight', dpi=300)
|
|
1543
|
+
plt.savefig(f'{output_base}.svg', bbox_inches='tight')
|
|
1544
|
+
print(f"Diagram saved: {output_base}.pdf/.png/.svg")
|
|
1545
|
+
plt.close()
|
|
1546
|
+
|
|
1547
|
+
# Step 2: Run quality checks
|
|
1548
|
+
print("\nRunning quality verification...")
|
|
1549
|
+
quality_report = run_quality_checks(
|
|
1550
|
+
f'{output_base}.png',
|
|
1551
|
+
output_dir=f'{output_base}_quality_reports'
|
|
1552
|
+
)
|
|
1553
|
+
|
|
1554
|
+
# Step 3: Review and iterate if needed
|
|
1555
|
+
if quality_report['overall_status'] != 'PASS':
|
|
1556
|
+
print("\n⚠️ Diagram needs review. Check quality reports for details.")
|
|
1557
|
+
return False
|
|
1558
|
+
else:
|
|
1559
|
+
print("\n✓ Diagram passed all quality checks!")
|
|
1560
|
+
return True
|
|
1561
|
+
|
|
1562
|
+
# Run complete workflow
|
|
1563
|
+
if __name__ == '__main__':
|
|
1564
|
+
success = create_flowchart_with_verification('my_flowchart')
|
|
1565
|
+
```
|
|
1566
|
+
|
|
1567
|
+
### Iterative Refinement Loop
|
|
1568
|
+
|
|
1569
|
+
For complex diagrams, use an iterative refinement process:
|
|
1570
|
+
|
|
1571
|
+
```python
|
|
1572
|
+
def iterative_diagram_refinement(create_function, max_iterations=3):
|
|
1573
|
+
"""
|
|
1574
|
+
Iteratively refine diagram until it passes quality checks.
|
|
1575
|
+
|
|
1576
|
+
Args:
|
|
1577
|
+
create_function: Function that creates and saves diagram
|
|
1578
|
+
max_iterations: Maximum refinement attempts
|
|
1579
|
+
"""
|
|
1580
|
+
for iteration in range(1, max_iterations + 1):
|
|
1581
|
+
print(f"\n{'='*60}")
|
|
1582
|
+
print(f"ITERATION {iteration}/{max_iterations}")
|
|
1583
|
+
print(f"{'='*60}")
|
|
1584
|
+
|
|
1585
|
+
# Create diagram
|
|
1586
|
+
diagram_path = create_function(iteration)
|
|
1587
|
+
|
|
1588
|
+
# Run checks
|
|
1589
|
+
quality_report = run_quality_checks(
|
|
1590
|
+
diagram_path,
|
|
1591
|
+
output_dir=f'iteration_{iteration}_reports'
|
|
1592
|
+
)
|
|
1593
|
+
|
|
1594
|
+
if quality_report['overall_status'] == 'PASS':
|
|
1595
|
+
print(f"\n✓ Diagram approved after {iteration} iteration(s)")
|
|
1596
|
+
return True
|
|
1597
|
+
else:
|
|
1598
|
+
print(f"\n⚠️ Issues found. Adjusting parameters for next iteration...")
|
|
1599
|
+
# Here you would adjust spacing, colors, etc. based on reports
|
|
1600
|
+
|
|
1601
|
+
print(f"\n❌ Maximum iterations reached. Manual review required.")
|
|
1602
|
+
return False
|
|
1603
|
+
```
|
|
1604
|
+
|
|
1605
|
+
## Common Use Cases
|
|
1606
|
+
|
|
1607
|
+
### Use Case 1: CONSORT Participant Flow Diagram
|
|
1608
|
+
|
|
1609
|
+
Clinical trials require standardized participant flow diagrams. Use the flowchart template:
|
|
1610
|
+
|
|
1611
|
+
```latex
|
|
1612
|
+
% Load template
|
|
1613
|
+
\input{assets/flowchart_template.tex}
|
|
1614
|
+
|
|
1615
|
+
% Customize with your numbers
|
|
1616
|
+
\begin{tikzpicture}[consort]
|
|
1617
|
+
\node (assessed) [flowbox] {Assessed for eligibility (n=500)};
|
|
1618
|
+
\node (excluded) [flowbox, below=of assessed] {Excluded (n=150)};
|
|
1619
|
+
\node (reasons) [infobox, right=of excluded] {
|
|
1620
|
+
\begin{tabular}{l}
|
|
1621
|
+
Age $<$ 18: n=80 \\
|
|
1622
|
+
Declined: n=50 \\
|
|
1623
|
+
Other: n=20
|
|
1624
|
+
\end{tabular}
|
|
1625
|
+
};
|
|
1626
|
+
% ... continue diagram
|
|
1627
|
+
\end{tikzpicture}
|
|
1628
|
+
```
|
|
1629
|
+
|
|
1630
|
+
See `assets/flowchart_template.tex` for complete template.
|
|
1631
|
+
|
|
1632
|
+
### Use Case 2: Electronics Circuit Schematic
|
|
1633
|
+
|
|
1634
|
+
For electronics papers, use Schemdraw or CircuitikZ:
|
|
1635
|
+
|
|
1636
|
+
```python
|
|
1637
|
+
# Python with Schemdraw - see scripts/circuit_generator.py
|
|
1638
|
+
from scripts.circuit_generator import create_circuit
|
|
1639
|
+
|
|
1640
|
+
circuit = create_circuit(
|
|
1641
|
+
components=['voltage_source', 'resistor', 'capacitor', 'ground'],
|
|
1642
|
+
values=['5V', '1kΩ', '10µF', None],
|
|
1643
|
+
layout='series'
|
|
1644
|
+
)
|
|
1645
|
+
circuit.save('my_circuit.pdf')
|
|
1646
|
+
```
|
|
1647
|
+
|
|
1648
|
+
Or use CircuitikZ in LaTeX - see `assets/circuit_template.tex`.
|
|
1649
|
+
|
|
1650
|
+
### Use Case 3: Biological Signaling Pathway
|
|
1651
|
+
|
|
1652
|
+
Visualize molecular interactions and signaling cascades:
|
|
1653
|
+
|
|
1654
|
+
```python
|
|
1655
|
+
# Python script - see scripts/pathway_diagram.py
|
|
1656
|
+
from scripts.pathway_diagram import PathwayGenerator
|
|
1657
|
+
|
|
1658
|
+
pathway = PathwayGenerator()
|
|
1659
|
+
pathway.add_protein('EGFR', position=(1, 5))
|
|
1660
|
+
pathway.add_protein('RAS', position=(3, 5))
|
|
1661
|
+
pathway.add_protein('RAF', position=(5, 5))
|
|
1662
|
+
pathway.add_activation('EGFR', 'RAS')
|
|
1663
|
+
pathway.add_activation('RAS', 'RAF')
|
|
1664
|
+
pathway.save('mapk_pathway.pdf')
|
|
1665
|
+
```
|
|
1666
|
+
|
|
1667
|
+
Or create in TikZ - see `assets/pathway_template.tex`.
|
|
1668
|
+
|
|
1669
|
+
### Use Case 4: System Architecture Diagram
|
|
1670
|
+
|
|
1671
|
+
Illustrate software/hardware components and relationships:
|
|
1672
|
+
|
|
1673
|
+
```latex
|
|
1674
|
+
% Use block diagram template
|
|
1675
|
+
\input{assets/block_diagram_template.tex}
|
|
1676
|
+
|
|
1677
|
+
\begin{tikzpicture}[architecture]
|
|
1678
|
+
\node (sensor) [component] {Sensor};
|
|
1679
|
+
\node (adc) [component, right=of sensor] {ADC};
|
|
1680
|
+
\node (micro) [component, right=of adc] {Microcontroller};
|
|
1681
|
+
\node (wifi) [component, above right=of micro] {WiFi Module};
|
|
1682
|
+
\node (display) [component, below right=of micro] {Display};
|
|
1683
|
+
|
|
1684
|
+
\draw [dataflow] (sensor) -- node[above] {Analog} (adc);
|
|
1685
|
+
\draw [dataflow] (adc) -- node[above] {Digital} (micro);
|
|
1686
|
+
\draw [dataflow] (micro) -- (wifi);
|
|
1687
|
+
\draw [dataflow] (micro) -- (display);
|
|
1688
|
+
\end{tikzpicture}
|
|
1689
|
+
```
|
|
1690
|
+
|
|
1691
|
+
See `assets/block_diagram_template.tex` for complete template.
|
|
1692
|
+
|
|
1693
|
+
## Helper Scripts
|
|
1694
|
+
|
|
1695
|
+
The `scripts/` directory contains Python utilities for automated diagram generation and quality verification:
|
|
1696
|
+
|
|
1697
|
+
### `generate_flowchart.py`
|
|
1698
|
+
|
|
1699
|
+
Convert text descriptions into TikZ flowcharts with automatic quality checks:
|
|
1700
|
+
|
|
1701
|
+
```python
|
|
1702
|
+
from scripts.generate_flowchart import text_to_flowchart, create_with_verification
|
|
1703
|
+
|
|
1704
|
+
description = """
|
|
1705
|
+
1. Screen participants (n=500)
|
|
1706
|
+
2. Exclude if age < 18 (n=150)
|
|
1707
|
+
3. Randomize remaining (n=350)
|
|
1708
|
+
4. Treatment group (n=175)
|
|
1709
|
+
5. Control group (n=175)
|
|
1710
|
+
6. Follow up at 3 months
|
|
1711
|
+
7. Analyze data
|
|
1712
|
+
"""
|
|
1713
|
+
|
|
1714
|
+
# Generate TikZ code
|
|
1715
|
+
tikz_code = text_to_flowchart(description)
|
|
1716
|
+
with open('methodology_flow.tex', 'w') as f:
|
|
1717
|
+
f.write(tikz_code)
|
|
1718
|
+
|
|
1719
|
+
# Or create with automatic verification
|
|
1720
|
+
success = create_with_verification(
|
|
1721
|
+
description,
|
|
1722
|
+
output='methodology_flow',
|
|
1723
|
+
verify=True
|
|
1724
|
+
)
|
|
1725
|
+
```
|
|
1726
|
+
|
|
1727
|
+
### `circuit_generator.py`
|
|
1728
|
+
|
|
1729
|
+
Generate circuit diagrams using Schemdraw with quality verification:
|
|
1730
|
+
|
|
1731
|
+
```python
|
|
1732
|
+
from scripts.circuit_generator import CircuitBuilder
|
|
1733
|
+
|
|
1734
|
+
builder = CircuitBuilder()
|
|
1735
|
+
builder.add_voltage_source('Vs', '5V')
|
|
1736
|
+
builder.add_resistor('R1', '1kΩ')
|
|
1737
|
+
builder.add_capacitor('C1', '10µF')
|
|
1738
|
+
builder.add_ground()
|
|
1739
|
+
|
|
1740
|
+
# Save with automatic quality checks
|
|
1741
|
+
builder.save('circuit.pdf', verify=True)
|
|
1742
|
+
|
|
1743
|
+
# Access quality report
|
|
1744
|
+
print(builder.quality_report)
|
|
1745
|
+
```
|
|
1746
|
+
|
|
1747
|
+
### `pathway_diagram.py`
|
|
1748
|
+
|
|
1749
|
+
Create biological pathway diagrams with overlap detection:
|
|
1750
|
+
|
|
1751
|
+
```python
|
|
1752
|
+
from scripts.pathway_diagram import PathwayGenerator
|
|
1753
|
+
|
|
1754
|
+
gen = PathwayGenerator(
|
|
1755
|
+
colorblind_safe=True,
|
|
1756
|
+
auto_spacing=True # Automatically adjust spacing to prevent overlaps
|
|
1757
|
+
)
|
|
1758
|
+
|
|
1759
|
+
gen.add_node('Receptor', type='protein', position=(1, 5))
|
|
1760
|
+
gen.add_node('Kinase', type='protein', position=(3, 5))
|
|
1761
|
+
gen.add_edge('Receptor', 'Kinase', interaction='activation')
|
|
1762
|
+
|
|
1763
|
+
# Save with quality verification
|
|
1764
|
+
quality_report = gen.save('pathway.pdf', verify=True)
|
|
1765
|
+
|
|
1766
|
+
# Iteratively refine if needed
|
|
1767
|
+
if quality_report['status'] != 'PASS':
|
|
1768
|
+
gen.auto_adjust_spacing()
|
|
1769
|
+
gen.save('pathway.pdf', verify=True)
|
|
1770
|
+
```
|
|
1771
|
+
|
|
1772
|
+
### `compile_tikz.py`
|
|
1773
|
+
|
|
1774
|
+
Standalone TikZ compilation utility with quality checks:
|
|
1775
|
+
|
|
1776
|
+
```bash
|
|
1777
|
+
# Compile TikZ to PDF with verification
|
|
1778
|
+
python scripts/compile_tikz.py flowchart.tex -o flowchart.pdf --verify
|
|
1779
|
+
|
|
1780
|
+
# Generate PNG with quality report
|
|
1781
|
+
python scripts/compile_tikz.py flowchart.tex -o flowchart.pdf --png --dpi 300 --verify
|
|
1782
|
+
|
|
1783
|
+
# Preview with quality overlay
|
|
1784
|
+
python scripts/compile_tikz.py flowchart.tex --preview --show-quality
|
|
1785
|
+
```
|
|
1786
|
+
|
|
1787
|
+
### `quality_checker.py`
|
|
1788
|
+
|
|
1789
|
+
Standalone quality verification tool for any diagram:
|
|
1790
|
+
|
|
1791
|
+
```bash
|
|
1792
|
+
# Check single diagram
|
|
1793
|
+
python scripts/quality_checker.py diagram.png
|
|
1794
|
+
|
|
1795
|
+
# Check with detailed report
|
|
1796
|
+
python scripts/quality_checker.py diagram.png --detailed --output-dir reports/
|
|
1797
|
+
|
|
1798
|
+
# Batch check multiple diagrams
|
|
1799
|
+
python scripts/quality_checker.py figures/*.png --batch
|
|
1800
|
+
|
|
1801
|
+
# Export visual comparison report
|
|
1802
|
+
python scripts/quality_checker.py diagram.png --visual-report
|
|
1803
|
+
```
|
|
1804
|
+
|
|
1805
|
+
```python
|
|
1806
|
+
# Python API
|
|
1807
|
+
from scripts.quality_checker import DiagramQualityChecker
|
|
1808
|
+
|
|
1809
|
+
checker = DiagramQualityChecker()
|
|
1810
|
+
|
|
1811
|
+
# Run all checks
|
|
1812
|
+
report = checker.check_diagram('diagram.png')
|
|
1813
|
+
|
|
1814
|
+
# Access specific checks
|
|
1815
|
+
overlap_report = checker.check_overlaps('diagram.png')
|
|
1816
|
+
accessibility_report = checker.check_accessibility('diagram.png')
|
|
1817
|
+
resolution_report = checker.check_resolution('diagram.png')
|
|
1818
|
+
|
|
1819
|
+
# Generate visual report
|
|
1820
|
+
checker.create_visual_report('diagram.png', output='quality_report.png')
|
|
1821
|
+
|
|
1822
|
+
# Batch processing
|
|
1823
|
+
results = checker.batch_check(['fig1.png', 'fig2.png', 'fig3.png'])
|
|
1824
|
+
checker.save_batch_report(results, 'batch_quality_report.json')
|
|
1825
|
+
```
|
|
1826
|
+
|
|
1827
|
+
## Templates and Assets
|
|
1828
|
+
|
|
1829
|
+
Pre-built templates in `assets/` directory provide starting points:
|
|
1830
|
+
|
|
1831
|
+
- **`flowchart_template.tex`** - Methodology flowcharts (CONSORT style)
|
|
1832
|
+
- **`circuit_template.tex`** - Electrical circuit diagrams
|
|
1833
|
+
- **`pathway_template.tex`** - Biological pathway diagrams
|
|
1834
|
+
- **`block_diagram_template.tex`** - System architecture diagrams
|
|
1835
|
+
- **`tikz_styles.tex`** - Reusable style definitions (ALWAYS load this)
|
|
1836
|
+
|
|
1837
|
+
All templates use colorblind-safe Okabe-Ito palette and publication-ready styling.
|
|
1838
|
+
|
|
1839
|
+
## Best Practices Summary
|
|
1840
|
+
|
|
1841
|
+
### Design Principles
|
|
1842
|
+
|
|
1843
|
+
1. **Clarity over complexity** - Simplify, remove unnecessary elements
|
|
1844
|
+
2. **Consistent styling** - Use templates and style files
|
|
1845
|
+
3. **Colorblind accessibility** - Use Okabe-Ito palette, redundant encoding
|
|
1846
|
+
4. **Appropriate typography** - Sans-serif fonts, minimum 7-8 pt
|
|
1847
|
+
5. **Vector format** - Always use PDF/SVG for publication
|
|
1848
|
+
|
|
1849
|
+
### Technical Requirements
|
|
1850
|
+
|
|
1851
|
+
1. **Resolution** - Vector preferred, or 300+ DPI for raster
|
|
1852
|
+
2. **File format** - PDF for LaTeX, SVG for web, PNG as fallback
|
|
1853
|
+
3. **Color space** - RGB for digital, CMYK for print (convert if needed)
|
|
1854
|
+
4. **Line weights** - Minimum 0.5 pt, typical 1-2 pt
|
|
1855
|
+
5. **Text size** - 7-8 pt minimum at final size
|
|
1856
|
+
|
|
1857
|
+
### Integration Guidelines
|
|
1858
|
+
|
|
1859
|
+
1. **Include in LaTeX** - Use `\input{}` for TikZ, `\includegraphics{}` for external
|
|
1860
|
+
2. **Caption thoroughly** - Describe all elements and abbreviations
|
|
1861
|
+
3. **Reference in text** - Explain diagram in narrative flow
|
|
1862
|
+
4. **Maintain consistency** - Same style across all figures in paper
|
|
1863
|
+
5. **Version control** - Keep source files (.tex, .py) in repository
|
|
1864
|
+
|
|
1865
|
+
## Troubleshooting Common Issues
|
|
1866
|
+
|
|
1867
|
+
### TikZ Compilation Errors
|
|
1868
|
+
|
|
1869
|
+
**Problem**: `! Package tikz Error: I do not know the key '/tikz/...`
|
|
1870
|
+
- **Solution**: Missing library - add `\usetikzlibrary{...}` to preamble
|
|
1871
|
+
|
|
1872
|
+
**Problem**: Overlapping text or elements
|
|
1873
|
+
- **Solution**: Run quality checker to identify overlaps: `python scripts/quality_checker.py diagram.png`
|
|
1874
|
+
- **Solution**: Increase `node distance`, adjust positioning manually based on overlap report
|
|
1875
|
+
- **Solution**: Use `auto_spacing=True` in pathway generator for automatic adjustment
|
|
1876
|
+
|
|
1877
|
+
**Problem**: Arrows not connecting properly
|
|
1878
|
+
- **Solution**: Use anchor points: `(node.east)`, `(node.north)`, etc.
|
|
1879
|
+
- **Solution**: Check overlap report for arrow/node intersections
|
|
1880
|
+
|
|
1881
|
+
### Python Generation Issues
|
|
1882
|
+
|
|
1883
|
+
**Problem**: Schemdraw elements not aligning
|
|
1884
|
+
- **Solution**: Use `.at()` method for precise positioning
|
|
1885
|
+
- **Solution**: Enable `auto_spacing` to prevent overlaps
|
|
1886
|
+
|
|
1887
|
+
**Problem**: Matplotlib text rendering issues
|
|
1888
|
+
- **Solution**: Set `plt.rcParams['text.usetex'] = True` for LaTeX rendering
|
|
1889
|
+
- **Solution**: Ensure LaTeX installation is available
|
|
1890
|
+
|
|
1891
|
+
**Problem**: Export quality poor
|
|
1892
|
+
- **Solution**: Increase DPI: `plt.savefig(..., dpi=300, bbox_inches='tight')`
|
|
1893
|
+
- **Solution**: Run resolution checker: `quality_checker.check_resolution(image_path, target_dpi=300)`
|
|
1894
|
+
|
|
1895
|
+
**Problem**: Elements overlap after generation
|
|
1896
|
+
- **Solution**: Run `detect_overlaps()` function to identify problem regions
|
|
1897
|
+
- **Solution**: Use iterative refinement: `iterative_diagram_refinement(create_function)`
|
|
1898
|
+
- **Solution**: Increase spacing between elements by 20-30%
|
|
1899
|
+
|
|
1900
|
+
### Quality Check Issues
|
|
1901
|
+
|
|
1902
|
+
**Problem**: False positive overlap detection
|
|
1903
|
+
- **Solution**: Adjust threshold: `detect_overlaps(image_path, threshold=0.98)`
|
|
1904
|
+
- **Solution**: Manually review flagged regions in visual report
|
|
1905
|
+
|
|
1906
|
+
**Problem**: Quality checker fails on PDF files
|
|
1907
|
+
- **Solution**: Convert PDF to PNG first: `from pdf2image import convert_from_path`
|
|
1908
|
+
- **Solution**: Use PNG output format for quality checks
|
|
1909
|
+
|
|
1910
|
+
**Problem**: Colorblind simulation shows poor contrast
|
|
1911
|
+
- **Solution**: Switch to Okabe-Ito palette explicitly in code
|
|
1912
|
+
- **Solution**: Add redundant encoding (shapes, patterns, line styles)
|
|
1913
|
+
- **Solution**: Increase color saturation and lightness differences
|
|
1914
|
+
|
|
1915
|
+
**Problem**: High-severity overlaps detected
|
|
1916
|
+
- **Solution**: Review overlap_report.json for exact positions
|
|
1917
|
+
- **Solution**: Increase spacing in those specific regions
|
|
1918
|
+
- **Solution**: Re-run with adjusted parameters and verify again
|
|
1919
|
+
|
|
1920
|
+
**Problem**: Visual report generation fails
|
|
1921
|
+
- **Solution**: Check Pillow and matplotlib installations
|
|
1922
|
+
- **Solution**: Ensure image file is readable: `Image.open(path).verify()`
|
|
1923
|
+
- **Solution**: Check sufficient disk space for report generation
|
|
1924
|
+
|
|
1925
|
+
### Accessibility Problems
|
|
1926
|
+
|
|
1927
|
+
**Problem**: Colors indistinguishable in grayscale
|
|
1928
|
+
- **Solution**: Run accessibility checker: `verify_accessibility(image_path)`
|
|
1929
|
+
- **Solution**: Add patterns, shapes, or line styles for redundancy
|
|
1930
|
+
- **Solution**: Increase contrast between adjacent elements
|
|
1931
|
+
|
|
1932
|
+
**Problem**: Text too small when printed
|
|
1933
|
+
- **Solution**: Run resolution validator: `validate_resolution(image_path)`
|
|
1934
|
+
- **Solution**: Design at final size, use minimum 7-8 pt fonts
|
|
1935
|
+
- **Solution**: Check physical dimensions in resolution report
|
|
1936
|
+
|
|
1937
|
+
**Problem**: Accessibility checks consistently fail
|
|
1938
|
+
- **Solution**: Review accessibility_report.json for specific failures
|
|
1939
|
+
- **Solution**: Increase color contrast by at least 20%
|
|
1940
|
+
- **Solution**: Test with actual grayscale conversion before finalizing
|
|
1941
|
+
|
|
1942
|
+
## Resources and References
|
|
1943
|
+
|
|
1944
|
+
### Detailed References
|
|
1945
|
+
|
|
1946
|
+
Load these files for comprehensive information on specific topics:
|
|
1947
|
+
|
|
1948
|
+
- **`references/tikz_guide.md`** - Complete TikZ syntax, positioning, styles, and techniques
|
|
1949
|
+
- **`references/diagram_types.md`** - Catalog of scientific diagram types with examples
|
|
1950
|
+
- **`references/best_practices.md`** - Publication standards and accessibility guidelines
|
|
1951
|
+
- **`references/python_libraries.md`** - Guide to Schemdraw, NetworkX, and Matplotlib for diagrams
|
|
1952
|
+
|
|
1953
|
+
### External Resources
|
|
1954
|
+
|
|
1955
|
+
**TikZ and LaTeX**
|
|
1956
|
+
- TikZ & PGF Manual: https://pgf-tikz.github.io/pgf/pgfmanual.pdf
|
|
1957
|
+
- TeXample.net: http://www.texample.net/tikz/ (examples gallery)
|
|
1958
|
+
- CircuitikZ Manual: https://ctan.org/pkg/circuitikz
|
|
1959
|
+
|
|
1960
|
+
**Python Libraries**
|
|
1961
|
+
- Schemdraw Documentation: https://schemdraw.readthedocs.io/
|
|
1962
|
+
- NetworkX Documentation: https://networkx.org/documentation/
|
|
1963
|
+
- Matplotlib Documentation: https://matplotlib.org/
|
|
1964
|
+
|
|
1965
|
+
**Publication Standards**
|
|
1966
|
+
- Nature Figure Guidelines: https://www.nature.com/nature/for-authors/final-submission
|
|
1967
|
+
- Science Figure Guidelines: https://www.science.org/content/page/instructions-preparing-initial-manuscript
|
|
1968
|
+
- CONSORT Diagram: http://www.consort-statement.org/consort-statement/flow-diagram
|
|
1969
|
+
|
|
1970
|
+
## Integration with Other Skills
|
|
1971
|
+
|
|
1972
|
+
This skill works synergistically with:
|
|
1973
|
+
|
|
1974
|
+
- **Scientific Writing** - Diagrams follow figure best practices
|
|
1975
|
+
- **Scientific Visualization** - Shares color palettes and styling
|
|
1976
|
+
- **LaTeX Posters** - Reuse TikZ styles for poster diagrams
|
|
1977
|
+
- **Research Grants** - Methodology diagrams for proposals
|
|
1978
|
+
- **Peer Review** - Evaluate diagram clarity and accessibility
|
|
1979
|
+
|
|
1980
|
+
## Quick Reference Checklist
|
|
1981
|
+
|
|
1982
|
+
Before submitting diagrams, verify:
|
|
1983
|
+
|
|
1984
|
+
### Visual Quality
|
|
1985
|
+
- [ ] Vector format (PDF/SVG) or 300+ DPI raster
|
|
1986
|
+
- [ ] No overlapping elements (verified by quality checker)
|
|
1987
|
+
- [ ] Adequate spacing between all components
|
|
1988
|
+
- [ ] Clean, professional alignment
|
|
1989
|
+
- [ ] All arrows connect properly to intended targets
|
|
1990
|
+
|
|
1991
|
+
### Accessibility
|
|
1992
|
+
- [ ] Colorblind-safe palette (Okabe-Ito) used
|
|
1993
|
+
- [ ] Works in grayscale (tested with accessibility checker)
|
|
1994
|
+
- [ ] Sufficient contrast between elements (verified)
|
|
1995
|
+
- [ ] Redundant encoding where appropriate (shapes + colors)
|
|
1996
|
+
- [ ] Colorblind simulation passes all checks
|
|
1997
|
+
|
|
1998
|
+
### Typography and Readability
|
|
1999
|
+
- [ ] Text minimum 7-8 pt at final size
|
|
2000
|
+
- [ ] All elements labeled clearly and completely
|
|
2001
|
+
- [ ] Consistent font family and sizing
|
|
2002
|
+
- [ ] No text overlaps or cutoffs
|
|
2003
|
+
- [ ] Units included where applicable
|
|
2004
|
+
|
|
2005
|
+
### Publication Standards
|
|
2006
|
+
- [ ] Consistent styling with other figures in manuscript
|
|
2007
|
+
- [ ] Comprehensive caption written with all abbreviations defined
|
|
2008
|
+
- [ ] Referenced appropriately in manuscript text
|
|
2009
|
+
- [ ] Meets journal-specific dimension requirements
|
|
2010
|
+
- [ ] Exported in required format for journal (PDF/EPS/TIFF)
|
|
2011
|
+
|
|
2012
|
+
### Quality Verification (Required)
|
|
2013
|
+
- [ ] Ran `run_quality_checks()` and achieved PASS status
|
|
2014
|
+
- [ ] Reviewed overlap detection report (zero high-severity overlaps)
|
|
2015
|
+
- [ ] Passed accessibility verification (grayscale and colorblind)
|
|
2016
|
+
- [ ] Resolution validated at target DPI (300+ for print)
|
|
2017
|
+
- [ ] Visual quality report generated and reviewed
|
|
2018
|
+
- [ ] All quality reports saved with figure files
|
|
2019
|
+
|
|
2020
|
+
### Documentation and Version Control
|
|
2021
|
+
- [ ] Source files (.tex, .py) saved for future revision
|
|
2022
|
+
- [ ] Quality reports archived in `quality_reports/` directory
|
|
2023
|
+
- [ ] Configuration parameters documented (colors, spacing, sizes)
|
|
2024
|
+
- [ ] Git commit includes source, output, and quality reports
|
|
2025
|
+
- [ ] README or comments explain how to regenerate figure
|
|
2026
|
+
|
|
2027
|
+
### Final Integration Check
|
|
2028
|
+
- [ ] Figure displays correctly in compiled manuscript
|
|
2029
|
+
- [ ] Cross-references work (`\ref{}` points to correct figure)
|
|
2030
|
+
- [ ] Figure number matches text citations
|
|
2031
|
+
- [ ] Caption appears on correct page relative to figure
|
|
2032
|
+
- [ ] No compilation warnings or errors related to figure
|
|
2033
|
+
|
|
2034
|
+
Use this skill to create clear, accessible, publication-quality diagrams that effectively communicate complex scientific concepts. The integrated quality verification workflow ensures all diagrams meet professional standards before publication.
|
|
2035
|
+
|