drawing-yh 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. drawing_yh-0.1.0/LICENSE +21 -0
  2. drawing_yh-0.1.0/PKG-INFO +18 -0
  3. drawing_yh-0.1.0/README.md +44 -0
  4. drawing_yh-0.1.0/drawing_yh/__init__.py +238 -0
  5. drawing_yh-0.1.0/drawing_yh/assembly/__init__.py +30 -0
  6. drawing_yh-0.1.0/drawing_yh/assembly/build_layout.py +506 -0
  7. drawing_yh-0.1.0/drawing_yh/bar/__init__.py +378 -0
  8. drawing_yh-0.1.0/drawing_yh/bar/circle/__init__.py +0 -0
  9. drawing_yh-0.1.0/drawing_yh/bar/circle/main.py +39 -0
  10. drawing_yh-0.1.0/drawing_yh/bar/enrichment_bar/__init__.py +0 -0
  11. drawing_yh-0.1.0/drawing_yh/bar/enrichment_bar/batch_enrich_tables_only.py +26 -0
  12. drawing_yh-0.1.0/drawing_yh/bar/enrichment_bar/enrichment_bar.py +247 -0
  13. drawing_yh-0.1.0/drawing_yh/bar/enrichment_bar/enrichment_bar_steps.py +116 -0
  14. drawing_yh-0.1.0/drawing_yh/bar/enrichment_bar/enrichment_batch.py +25 -0
  15. drawing_yh-0.1.0/drawing_yh/bar/horizontal/__init__.py +0 -0
  16. drawing_yh-0.1.0/drawing_yh/bar/horizontal/horizontal.py +117 -0
  17. drawing_yh-0.1.0/drawing_yh/bar/horizontal/horizontal_black_and_white.py +114 -0
  18. drawing_yh-0.1.0/drawing_yh/bar/horizontal/main.py +67 -0
  19. drawing_yh-0.1.0/drawing_yh/bar/horizontal/subplot.py +64 -0
  20. drawing_yh-0.1.0/drawing_yh/bar/waterfall/__init__.py +1 -0
  21. drawing_yh-0.1.0/drawing_yh/bar/waterfall/main.py +25 -0
  22. drawing_yh-0.1.0/drawing_yh/bar/waterfall/waterfall.py +156 -0
  23. drawing_yh-0.1.0/drawing_yh/box_plot/__init__.py +263 -0
  24. drawing_yh-0.1.0/drawing_yh/bubble/__init__.py +15 -0
  25. drawing_yh-0.1.0/drawing_yh/bubble/bubble_plot.py +314 -0
  26. drawing_yh-0.1.0/drawing_yh/cell_schematic/__init__.py +173 -0
  27. drawing_yh-0.1.0/drawing_yh/chord/__init__.py +15 -0
  28. drawing_yh-0.1.0/drawing_yh/chord/_mpl_chord/__init__.py +9 -0
  29. drawing_yh-0.1.0/drawing_yh/chord/_mpl_chord/chord_diagram.py +692 -0
  30. drawing_yh-0.1.0/drawing_yh/chord/_mpl_chord/gradient.py +55 -0
  31. drawing_yh-0.1.0/drawing_yh/chord/_mpl_chord/utilities.py +202 -0
  32. drawing_yh-0.1.0/drawing_yh/chord/main.py +1131 -0
  33. drawing_yh-0.1.0/drawing_yh/color.py +87 -0
  34. drawing_yh-0.1.0/drawing_yh/deg_hierarchy.py +156 -0
  35. drawing_yh-0.1.0/drawing_yh/dose_response/PingYi.py +126 -0
  36. drawing_yh-0.1.0/drawing_yh/dose_response/__init__.py +0 -0
  37. drawing_yh-0.1.0/drawing_yh/dose_response/create_para.py +104 -0
  38. drawing_yh-0.1.0/drawing_yh/dose_response/fig.py +164 -0
  39. drawing_yh-0.1.0/drawing_yh/dose_response/heatmap_with_colorbar.py +68 -0
  40. drawing_yh-0.1.0/drawing_yh/dose_response/main.py +24 -0
  41. drawing_yh-0.1.0/drawing_yh/dose_response/predicted_viability.py +110 -0
  42. drawing_yh-0.1.0/drawing_yh/dose_response/read_file.py +118 -0
  43. drawing_yh-0.1.0/drawing_yh/dotplot/pathway_effect.py +135 -0
  44. drawing_yh-0.1.0/drawing_yh/dotplot.py +598 -0
  45. drawing_yh-0.1.0/drawing_yh/dumbbell.py +233 -0
  46. drawing_yh-0.1.0/drawing_yh/embedding.py +536 -0
  47. drawing_yh-0.1.0/drawing_yh/embedding_domain.py +693 -0
  48. drawing_yh-0.1.0/drawing_yh/heatmap/B_cell_ratio_heatmap.py +147 -0
  49. drawing_yh-0.1.0/drawing_yh/heatmap/__init__.py +96 -0
  50. drawing_yh-0.1.0/drawing_yh/heatmap/core.py +456 -0
  51. drawing_yh-0.1.0/drawing_yh/heatmap/enrichment_dotplot.py +272 -0
  52. drawing_yh-0.1.0/drawing_yh/heatmap/heapmap_3D/__init__.py +16 -0
  53. drawing_yh-0.1.0/drawing_yh/heatmap/heapmap_3D/heatmap_fan_species.py +204 -0
  54. drawing_yh-0.1.0/drawing_yh/heatmap/heapmap_3D/heatmap_with_icon.py +313 -0
  55. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_by_pattern/KEGG/main.py +178 -0
  56. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_by_pattern/KEGG_sex/main.py +186 -0
  57. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_by_pattern/__init__.py +1 -0
  58. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_by_pattern/heatmap_by_pattern.py +311 -0
  59. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_by_pattern/protein/main.py +162 -0
  60. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_by_pattern/protein_sex/main.py +171 -0
  61. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/HMM 20241125/cluster-3.py +238 -0
  62. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/HMM 20241125/cluster.py +164 -0
  63. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/HMM 20241126/cluster-1.py +180 -0
  64. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/HMM 20241126/cluster-2.py +180 -0
  65. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/HMM 20241126/cluster-3.py +233 -0
  66. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/HMM 20241126/heatmap.py +105 -0
  67. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/__init__.py +4 -0
  68. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/clustermap_annot.py +411 -0
  69. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_clustered/heapmap_clustered.py +148 -0
  70. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_tile_style/__init__.py +4 -0
  71. drawing_yh-0.1.0/drawing_yh/heatmap/heatmap_tile_style/heatmap_tile_style.py +98 -0
  72. drawing_yh-0.1.0/drawing_yh/heatmap/oydeg_enrichment.py +712 -0
  73. drawing_yh-0.1.0/drawing_yh/heatmap/rescue_arrow.py +766 -0
  74. drawing_yh-0.1.0/drawing_yh/heatmap/row_bars.py +372 -0
  75. drawing_yh-0.1.0/drawing_yh/histogram/__init__.py +196 -0
  76. drawing_yh-0.1.0/drawing_yh/hybrid_chart/__init__.py +0 -0
  77. drawing_yh-0.1.0/drawing_yh/hybrid_chart/age_dotmap_by_pattern.py +234 -0
  78. drawing_yh-0.1.0/drawing_yh/hybrid_chart/dpmp_pathway_link/__init__.py +4 -0
  79. drawing_yh-0.1.0/drawing_yh/hybrid_chart/dpmp_pathway_link/dpmp_pathway_link.py +304 -0
  80. drawing_yh-0.1.0/drawing_yh/icon/__init__.py +145 -0
  81. drawing_yh-0.1.0/drawing_yh/icon/_generate_human_frontal.py +112 -0
  82. drawing_yh-0.1.0/drawing_yh/icon/_generate_pancreas_adrenal.py +97 -0
  83. drawing_yh-0.1.0/drawing_yh/icon/_rasterize_lymphnode.py +109 -0
  84. drawing_yh-0.1.0/drawing_yh/icon/_rasterize_svg.py +248 -0
  85. drawing_yh-0.1.0/drawing_yh/icon/generate_missing_icons.py +529 -0
  86. drawing_yh-0.1.0/drawing_yh/icon/read_svg.py +29 -0
  87. drawing_yh-0.1.0/drawing_yh/icon/test.py +35 -0
  88. drawing_yh-0.1.0/drawing_yh/illustrator/__init__.py +0 -0
  89. drawing_yh-0.1.0/drawing_yh/illustrator/figure_panel.py +94 -0
  90. drawing_yh-0.1.0/drawing_yh/illustrator/main.py +40 -0
  91. drawing_yh-0.1.0/drawing_yh/io.py +174 -0
  92. drawing_yh-0.1.0/drawing_yh/layout.py +236 -0
  93. drawing_yh-0.1.0/drawing_yh/layout_audit.py +273 -0
  94. drawing_yh-0.1.0/drawing_yh/lollipop.py +100 -0
  95. drawing_yh-0.1.0/drawing_yh/michaelis_menten/MM_curve-test.py +194 -0
  96. drawing_yh-0.1.0/drawing_yh/michaelis_menten/MM_curve.py +229 -0
  97. drawing_yh-0.1.0/drawing_yh/michaelis_menten/Michaelis-Menten.py +98 -0
  98. drawing_yh-0.1.0/drawing_yh/michaelis_menten/__init__.py +0 -0
  99. drawing_yh-0.1.0/drawing_yh/network/__init__.py +50 -0
  100. drawing_yh-0.1.0/drawing_yh/network/edges.py +65 -0
  101. drawing_yh-0.1.0/drawing_yh/network/halo.py +144 -0
  102. drawing_yh-0.1.0/drawing_yh/network/hub_spoke.py +419 -0
  103. drawing_yh-0.1.0/drawing_yh/network/labels.py +165 -0
  104. drawing_yh-0.1.0/drawing_yh/network/layout.py +377 -0
  105. drawing_yh-0.1.0/drawing_yh/network/modular.py +1276 -0
  106. drawing_yh-0.1.0/drawing_yh/network/palette.py +62 -0
  107. drawing_yh-0.1.0/drawing_yh/palettes.py +174 -0
  108. drawing_yh-0.1.0/drawing_yh/pca/PCA.py +130 -0
  109. drawing_yh-0.1.0/drawing_yh/pca/PCA_test.py +264 -0
  110. drawing_yh-0.1.0/drawing_yh/pca/PLS-DA.py +176 -0
  111. drawing_yh-0.1.0/drawing_yh/pca/__init__.py +348 -0
  112. drawing_yh-0.1.0/drawing_yh/pca/main.py +100 -0
  113. drawing_yh-0.1.0/drawing_yh/pie_chart/donut/main.py +23 -0
  114. drawing_yh-0.1.0/drawing_yh/pie_chart/explode/main.py +24 -0
  115. drawing_yh-0.1.0/drawing_yh/pie_chart/pie/main.py +22 -0
  116. drawing_yh-0.1.0/drawing_yh/pie_chart/pie_chart.py +343 -0
  117. drawing_yh-0.1.0/drawing_yh/pie_chart/zoom_pie/main.py +38 -0
  118. drawing_yh-0.1.0/drawing_yh/pie_chart/zoom_pie.py +667 -0
  119. drawing_yh-0.1.0/drawing_yh/proportion_strip.py +155 -0
  120. drawing_yh-0.1.0/drawing_yh/report/__init__.py +62 -0
  121. drawing_yh-0.1.0/drawing_yh/report/legacy_ppt.py +4 -0
  122. drawing_yh-0.1.0/drawing_yh/report/ppt_engine.py +4 -0
  123. drawing_yh-0.1.0/drawing_yh/report/templates/build_combined_report_template.py +439 -0
  124. drawing_yh-0.1.0/drawing_yh/report/templates/md_to_pptx_template.py +934 -0
  125. drawing_yh-0.1.0/drawing_yh/report/templates/serve_nocache_template.py +31 -0
  126. drawing_yh-0.1.0/drawing_yh/report/templates/watch_build_template.py +146 -0
  127. drawing_yh-0.1.0/drawing_yh/scatter/__init__.py +8 -0
  128. drawing_yh-0.1.0/drawing_yh/scatter/bubble/__init__.py +2 -0
  129. drawing_yh-0.1.0/drawing_yh/scatter/bubble/example_bcell_ratio.py +158 -0
  130. drawing_yh-0.1.0/drawing_yh/scatter/bubble/example_bcell_tissue.py +158 -0
  131. drawing_yh-0.1.0/drawing_yh/scatter/bubble/example_metabolomics.py +204 -0
  132. drawing_yh-0.1.0/drawing_yh/scatter/bubble/example_proteomics.py +193 -0
  133. drawing_yh-0.1.0/drawing_yh/scatter/da_dot_summary/__init__.py +3 -0
  134. drawing_yh-0.1.0/drawing_yh/scatter/da_dot_summary/da_dot_summary.py +245 -0
  135. drawing_yh-0.1.0/drawing_yh/scatter/dot_chart/__init__.py +0 -0
  136. drawing_yh-0.1.0/drawing_yh/scatter/dot_chart/dot_chart.py +266 -0
  137. drawing_yh-0.1.0/drawing_yh/scatter/dot_chart/example_dot_chart.py +251 -0
  138. drawing_yh-0.1.0/drawing_yh/scatter/linear_fit/__init__.py +1 -0
  139. drawing_yh-0.1.0/drawing_yh/scatter/linear_fit/example_bcell.py +91 -0
  140. drawing_yh-0.1.0/drawing_yh/scatter/linear_fit/example_color_palette.py +75 -0
  141. drawing_yh-0.1.0/drawing_yh/scatter/linear_fit/linear_fit.py +318 -0
  142. drawing_yh-0.1.0/drawing_yh/scatter/poly_fit/__init__.py +1 -0
  143. drawing_yh-0.1.0/drawing_yh/scatter/poly_fit/main.py +32 -0
  144. drawing_yh-0.1.0/drawing_yh/scatter/poly_fit/original_scatter.py +58 -0
  145. drawing_yh-0.1.0/drawing_yh/scatter/poly_fit/poly_fit.py +76 -0
  146. drawing_yh-0.1.0/drawing_yh/scatter/rank_plot/__init__.py +1 -0
  147. drawing_yh-0.1.0/drawing_yh/scatter/rank_plot/main.py +40 -0
  148. drawing_yh-0.1.0/drawing_yh/scatter/rank_plot/original_sort_fig.py +100 -0
  149. drawing_yh-0.1.0/drawing_yh/scatter/rank_plot/rank_plot.py +125 -0
  150. drawing_yh-0.1.0/drawing_yh/scatter/simple_scatter/__init__.py +3 -0
  151. drawing_yh-0.1.0/drawing_yh/scatter/simple_scatter/example_species_merge.py +147 -0
  152. drawing_yh-0.1.0/drawing_yh/scatter/simple_scatter/main.py +94 -0
  153. drawing_yh-0.1.0/drawing_yh/scatter/threshold_scatter.py +167 -0
  154. drawing_yh-0.1.0/drawing_yh/text_editable.py +28 -0
  155. drawing_yh-0.1.0/drawing_yh/tile_heatmap.py +211 -0
  156. drawing_yh-0.1.0/drawing_yh/umap_overlay.py +503 -0
  157. drawing_yh-0.1.0/drawing_yh/venn/__init__.py +5 -0
  158. drawing_yh-0.1.0/drawing_yh/venn/venn_plot.py +205 -0
  159. drawing_yh-0.1.0/drawing_yh/violin_plot/__init__.py +0 -0
  160. drawing_yh-0.1.0/drawing_yh/violin_plot/main.py +67 -0
  161. drawing_yh-0.1.0/drawing_yh/violin_plot/violin_adata.py +787 -0
  162. drawing_yh-0.1.0/drawing_yh/violin_plot/violin_function.py +187 -0
  163. drawing_yh-0.1.0/drawing_yh/volcano_plot/__init__.py +5 -0
  164. drawing_yh-0.1.0/drawing_yh/volcano_plot/volcano.py +193 -0
  165. drawing_yh-0.1.0/drawing_yh/volcano_plot/volcano_rails.py +478 -0
  166. drawing_yh-0.1.0/drawing_yh/volcano_plot/volcano_with_intensity.py +132 -0
  167. drawing_yh-0.1.0/drawing_yh.egg-info/PKG-INFO +18 -0
  168. drawing_yh-0.1.0/drawing_yh.egg-info/SOURCES.txt +173 -0
  169. drawing_yh-0.1.0/drawing_yh.egg-info/dependency_links.txt +1 -0
  170. drawing_yh-0.1.0/drawing_yh.egg-info/requires.txt +13 -0
  171. drawing_yh-0.1.0/drawing_yh.egg-info/top_level.txt +1 -0
  172. drawing_yh-0.1.0/pyproject.toml +40 -0
  173. drawing_yh-0.1.0/setup.cfg +4 -0
  174. drawing_yh-0.1.0/tests/test_cell_schematic.py +41 -0
  175. drawing_yh-0.1.0/tests/test_ppt_engine.py +139 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Genesi599
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.4
2
+ Name: drawing-yh
3
+ Version: 0.1.0
4
+ Summary: Publication-quality scientific figures with automated layout audits: volcano, heatmap, PCA, violin, chord, venn, and more
5
+ Requires-Python: >=3.8
6
+ License-File: LICENSE
7
+ Requires-Dist: matplotlib
8
+ Requires-Dist: numpy
9
+ Requires-Dist: pandas
10
+ Requires-Dist: scipy
11
+ Requires-Dist: shapely
12
+ Requires-Dist: scikit-learn
13
+ Requires-Dist: matplotlib-venn
14
+ Requires-Dist: pycirclize
15
+ Requires-Dist: Pillow
16
+ Requires-Dist: python-pptx
17
+ Requires-Dist: pywin32; platform_system == "Windows"
18
+ Dynamic: license-file
@@ -0,0 +1,44 @@
1
+ # python-drawing-yh (`drawing_yh`)
2
+
3
+ Publication-quality scientific plotting toolkit for Python — the plotting layer behind multi-module slide-style research reports.
4
+
5
+ `import drawing_yh` applies the house style automatically (Arial, 8 pt base, editable text in SVG/PDF, three-format export), and every chart family ships as a reusable template instead of ad-hoc scripts.
6
+
7
+ ## Highlights
8
+
9
+ - **Chart families** — bar / box / heatmap / scatter / violin / volcano / PCA / venn / pie / network / chord / dotplot / dumbbell / lollipop / embedding / dose-response / Michaelis-Menten … each with a documented template module.
10
+ - **Report suite (`drawing_yh.report`)** — Markdown → multi-module slide-style HTML websites (three-level nav: module / chapter / section) and same-source native PPTX inheriting a master theme. See the companion skill [local-report-builder](https://github.com/Genesi599/local-report-builder) for the full playbook.
11
+ - **Text audit helpers** — `get_text_bboxes` / `find_overlaps` to programmatically verify no text overlaps or canvas overflow (the two hard rules every figure must pass).
12
+ - **Style constants** — Okabe-Ito / DEEP-20 / age / sex / species palettes, `compute_figsize` layout helpers, `save_fig` one-call pdf+png+svg export.
13
+ - **Example gallery** — `example_gallery/` renders one preview per template; rebuilt automatically by a pre-commit hook when templates change.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ pip install -e . # from a checkout
19
+ ```
20
+
21
+ Requires Python ≥ 3.11, matplotlib / numpy / pandas / scipy, plus `matplotlib-venn` and `pycirclize` for those chart families. The report suite additionally needs system `pandoc`, `python-pptx` and `Pillow`.
22
+
23
+ ## Usage sketch
24
+
25
+ ```python
26
+ import drawing_yh # applies rcParams (Arial 8pt, editable fonts)
27
+ from drawing_yh import save_fig # pdf + png + svg in one call
28
+
29
+ fig, ax = plt.subplots()
30
+ ...
31
+ save_fig(fig, "my_figure.pdf", also=(".png", ".svg"))
32
+ ```
33
+
34
+ ## Conventions (STANDARDS.md)
35
+
36
+ - Base font 8 pt locked; figure size adapts to content, never the other way.
37
+ - All text in English inside figures; significance markers as plain black `*`.
38
+ - Every figure ships with a plotted-data CSV sidecar where applicable.
39
+
40
+ See `STANDARDS.md` for the full checklist.
41
+
42
+ ## License
43
+
44
+ MIT
@@ -0,0 +1,238 @@
1
+ """
2
+ drawing_yh — Python 科研作图工具包
3
+
4
+ **import 即应用项目科研出图标准**(可编辑字体、Arial、SVG 不转曲、统一字号),
5
+ 并导出常用工具:`save_fig`、命名色板、`compute_figsize`、文字防重叠 helper。
6
+
7
+ 完整标准见包根 `STANDARDS.md`,或 `LLM-yh/LLM_textbook/sci_plot_subplot_notes.md`。
8
+
9
+ Quick start
10
+ -----------
11
+ from drawing_yh import save_fig, OKABE_ITO, compute_figsize, DOUBLE_COL_IN
12
+ import matplotlib.pyplot as plt
13
+
14
+ fig, ax = plt.subplots(figsize=compute_figsize(n_items=len(df),
15
+ width=DOUBLE_COL_IN))
16
+ # ... 用 OKABE_ITO 或 DEEP_20 上色 ...
17
+ save_fig(fig, 'out/fig1.pdf', also=('.png', '.svg')) # 一次写三份
18
+ """
19
+ from importlib.metadata import version, PackageNotFoundError
20
+ import matplotlib as _mpl
21
+
22
+ try:
23
+ __version__ = version("drawing-yh")
24
+ except PackageNotFoundError:
25
+ __version__ = "0.0.0"
26
+
27
+
28
+ # ============================================================
29
+ # 项目常量
30
+ # ============================================================
31
+ DEFAULT_FONT_SIZE = 8 # 印刷字号(5–8pt 范围,统一 8)
32
+ SVG_DPI = 72 # SVG 必须 72 才能 1:1 渲染文字
33
+ PNG_DPI = 300 # PNG 默认印刷质量
34
+
35
+ SINGLE_COL_IN = 3.35 # 单栏 ~ 8.5 cm
36
+ ONE_HALF_COL_IN = 4.49 # 1.5 栏 ~ 11.4 cm
37
+ DOUBLE_COL_IN = 6.89 # 双栏 ~ 17.5 cm
38
+
39
+
40
+ # ============================================================
41
+ # rcParams —— 包级一次性设置(import 时生效)
42
+ # ============================================================
43
+ RC_DEFAULTS = {
44
+ # —— 字体可编辑性(投稿必需)——
45
+ 'pdf.fonttype': 42, # 嵌入 TrueType,Illustrator 可编辑
46
+ 'ps.fonttype': 42,
47
+ 'svg.fonttype': 'none', # SVG 文字保持文字对象,不转曲
48
+ 'pdf.use14corefonts': False, # 不替换为不可编辑的核心字体
49
+ # —— 字体 ——
50
+ 'font.family': 'Arial', # 期刊通用;装不上会回退到默认 sans-serif
51
+ 'font.size': DEFAULT_FONT_SIZE,
52
+ 'axes.titlesize': DEFAULT_FONT_SIZE,
53
+ 'axes.labelsize': DEFAULT_FONT_SIZE,
54
+ 'xtick.labelsize': DEFAULT_FONT_SIZE,
55
+ 'ytick.labelsize': DEFAULT_FONT_SIZE,
56
+ 'legend.fontsize': DEFAULT_FONT_SIZE,
57
+ 'figure.titlesize': DEFAULT_FONT_SIZE,
58
+ # —— 保存默认 ——
59
+ 'savefig.bbox': 'tight',
60
+ 'savefig.pad_inches': 0.02,
61
+ 'savefig.facecolor': 'white',
62
+ }
63
+
64
+
65
+ def set_rc(overrides: dict = None) -> None:
66
+ """
67
+ 应用项目标准 rcParams。
68
+
69
+ 包 import 时已自动调用一次。如果脚本里临时改了 rc(比如调字号),
70
+ 想恢复到标准,可以再 `drawing_yh.set_rc()` 一下。
71
+ """
72
+ rc = dict(RC_DEFAULTS)
73
+ if overrides:
74
+ rc.update(overrides)
75
+ _mpl.rcParams.update(rc)
76
+
77
+
78
+ # 包加载时立即应用一次;所有 `import drawing_yh` / `from drawing_yh import …`
79
+ # 的脚本都自动享受标准 rc,不必每个文件再写一遍。
80
+ set_rc()
81
+
82
+
83
+ # ============================================================
84
+ # 顶层导出
85
+ # ============================================================
86
+ from .io import save_fig # noqa: E402
87
+ from .palettes import ( # noqa: E402
88
+ OKABE_ITO, DEEP_20, AGE_GRADIENT, SEX, SPECIES, THREE_GROUP,
89
+ to_grayscale, grayscale_distinct, preview_palette, family_palette,
90
+ )
91
+ from .layout import ( # noqa: E402
92
+ compute_figsize, get_text_bboxes, find_overlaps, nudge_no_overlap_y,
93
+ autoshrink_figsize,
94
+ TextBBox,
95
+ )
96
+ from .dumbbell import render_mean_dumbbell # noqa: E402
97
+ from .venn import venn_diagram # noqa: E402
98
+ from .dotplot import ( # noqa: E402
99
+ marker_dotplot,
100
+ dot_sizes, pad_axes, style_colorbar,
101
+ add_size_legend, add_block_separators, add_row_color_dots,
102
+ )
103
+ from . import dotplot # noqa: E402,F401
104
+ from .embedding import ( # noqa: E402
105
+ feature_plot,
106
+ resolve_vlim, scatter_embedding, add_embedding_axes, auto_ncols,
107
+ cluster_atlas, cluster_centroids,
108
+ )
109
+ from . import embedding # noqa: E402,F401
110
+ from .embedding_domain import ( # noqa: E402
111
+ GapfilledOutlineResult,
112
+ gapfilled_embedding_outline,
113
+ draw_gapfilled_embedding_domains,
114
+ embedding_knn_density_mask,
115
+ filter_main_embedding_components,
116
+ label_point_for_outline,
117
+ trim_points_inside_reference_domain,
118
+ )
119
+ from .heatmap import (heatmap_with_row_bars, clustermap_annot, # noqa: E402
120
+ plot_oydeg_heatmap_enrichment,
121
+ plot_enrichment_dotplot, pick_enrich_terms,
122
+ plot_rescue_arrow_heatmap,
123
+ plot_staircase_rescue_heatmap, missingness_matrix)
124
+ from . import report # noqa: E402,F401
125
+ from .network import hub_spoke # noqa: E402
126
+ from .volcano_plot import volcano, volcano_with_gene_rails # noqa: E402
127
+ from .umap_overlay import ( # noqa: E402
128
+ DA_CMAP, GRAY_NA,
129
+ draw_da_umap_panel, build_key_lines, umap_value_panels,
130
+ )
131
+ from . import umap_overlay # noqa: E402,F401
132
+ from .bubble import bubble_plot, two_tone_ticklabels # noqa: E402
133
+ from . import bubble # noqa: E402,F401
134
+ from .box_plot import box_strip, box_stats # noqa: E402
135
+ from . import box_plot # noqa: E402,F401
136
+ from .bar import grouped_stack_bar, grouped_hbar, enrich_up_down # noqa: E402
137
+ from . import bar # noqa: E402,F401
138
+ from .histogram import hist_panel, hist_grid # noqa: E402
139
+ from . import histogram # noqa: E402,F401
140
+ from .scatter import threshold_scatter # noqa: E402
141
+ from .scatter import da_dot_summary # noqa: E402
142
+ from . import scatter # noqa: E402,F401
143
+ from .proportion_strip import ( # noqa: E402
144
+ DEFAULT_AGE_COLORS,
145
+ fraction_by_age_panel, fraction_by_age_figure,
146
+ )
147
+ from . import proportion_strip # noqa: E402,F401
148
+ from .pca import parallel_centroid_guides, pca_score_plot, pca_iqr_outlier_screen # noqa: E402
149
+ from . import pca as pca # noqa: E402,F401
150
+ from .tile_heatmap import tile_heatmap # noqa: E402
151
+ from .lollipop import lollipop_plot # noqa: E402
152
+ from .cell_schematic import ( # noqa: E402
153
+ IconPlacement,
154
+ copy_flat_cell_template,
155
+ default_anchor_map,
156
+ flat_cell_attribution_path,
157
+ flat_cell_preview_path,
158
+ flat_cell_template_path,
159
+ )
160
+ from . import cell_schematic # noqa: E402,F401
161
+
162
+ __all__ = [
163
+ # version
164
+ "__version__",
165
+ # constants
166
+ "DEFAULT_FONT_SIZE", "SVG_DPI", "PNG_DPI",
167
+ "SINGLE_COL_IN", "ONE_HALF_COL_IN", "DOUBLE_COL_IN",
168
+ "RC_DEFAULTS",
169
+ # rc
170
+ "set_rc",
171
+ # io
172
+ "save_fig",
173
+ # palettes
174
+ "OKABE_ITO", "DEEP_20", "AGE_GRADIENT", "SEX", "SPECIES", "THREE_GROUP",
175
+ "to_grayscale", "grayscale_distinct", "preview_palette", "family_palette",
176
+ # layout
177
+ "compute_figsize", "get_text_bboxes", "find_overlaps",
178
+ "nudge_no_overlap_y", "autoshrink_figsize", "TextBBox",
179
+ # charts
180
+ "render_mean_dumbbell",
181
+ "venn_diagram",
182
+ "marker_dotplot",
183
+ "feature_plot",
184
+ "pca_score_plot",
185
+ "heatmap_with_row_bars",
186
+ "plot_oydeg_heatmap_enrichment",
187
+ "plot_rescue_arrow_heatmap",
188
+ "plot_staircase_rescue_heatmap",
189
+ "plot_enrichment_dotplot",
190
+ "pick_enrich_terms",
191
+ "clustermap_annot",
192
+ # dot-plot style primitives (re-exported from drawing_yh.dotplot)
193
+ "dot_sizes", "pad_axes", "style_colorbar",
194
+ "add_size_legend", "add_block_separators", "add_row_color_dots",
195
+ # embedding feature-plot primitives (re-exported from drawing_yh.embedding)
196
+ "resolve_vlim", "scatter_embedding", "add_embedding_axes", "auto_ncols",
197
+ "cluster_atlas", "cluster_centroids",
198
+ "GapfilledOutlineResult", "gapfilled_embedding_outline",
199
+ "draw_gapfilled_embedding_domains", "embedding_knn_density_mask",
200
+ "filter_main_embedding_components", "label_point_for_outline",
201
+ "trim_points_inside_reference_domain",
202
+ # subpackages
203
+ "dotplot",
204
+ "embedding",
205
+ "report",
206
+ # network
207
+ "hub_spoke",
208
+ # umap value-overlay
209
+ "DA_CMAP", "GRAY_NA",
210
+ "draw_da_umap_panel", "build_key_lines", "umap_value_panels",
211
+ "umap_overlay",
212
+ # bubble plot
213
+ "bubble_plot", "two_tone_ticklabels",
214
+ "bubble",
215
+ # box plot (grouped boxes + optional per-sample points)
216
+ "box_strip", "box_stats", "box_plot",
217
+ # bar (grouped / stacked / grouped-horizontal)
218
+ "grouped_stack_bar", "grouped_hbar", "enrich_up_down", "bar",
219
+ # histogram (distribution of a numeric vector)
220
+ "hist_panel", "hist_grid", "histogram",
221
+ # threshold scatter (continuous x/y + highlight mask)
222
+ "threshold_scatter", "scatter",
223
+ # proportion strip (boxplot + dots)
224
+ "DEFAULT_AGE_COLORS",
225
+ "fraction_by_age_panel", "fraction_by_age_figure",
226
+ "proportion_strip",
227
+ # tile heatmap (TF-style square-cell)
228
+ "tile_heatmap",
229
+ # lollipop / stem plot
230
+ "lollipop_plot",
231
+ # flat editable cell schematic
232
+ "IconPlacement", "copy_flat_cell_template", "default_anchor_map",
233
+ "flat_cell_attribution_path", "flat_cell_preview_path",
234
+ "flat_cell_template_path", "cell_schematic",
235
+ "pca_iqr_outlier_screen",
236
+ ]
237
+ from .layout_audit import audit_layout, LayoutAuditError # noqa: E402
238
+ from . import layout_audit # noqa: E402,F401
@@ -0,0 +1,30 @@
1
+ """drawing_yh.assembly — 统一排图工具(2026-09-02 合并:
2
+ 原 figure_assembly/build_layout.py 的 flow 排版 + MRI-yh/assemble_age_compare.py 的固定网格算法)。
3
+
4
+ 模式(每页 page 级 `mode` 键):
5
+ flow(默认) — 子图保持原始物理尺寸(不缩放, 2026-09-02 用户确认规则)逐行流式排版,
6
+ 画布按内容自适应; 超宽面板单独成行。
7
+ grid — 固定网格(原 assemble_age_compare 算法): cell 尺寸 + 行分组标签 +
8
+ 顶部标题, 每格内 thumbnail 式等比 fit 居中(默认只缩不放, enlarge=true 才放大)。
9
+ abs — 面板显式 x_mm/y_mm 绝对定位(旧布局表兼容)。
10
+ 有意缩放: 任何模式下面板显式 width_mm/height_mm 即覆盖自然尺寸(须在 YAML 注释原因)。
11
+
12
+ 用法:
13
+ python -m drawing_yh.assembly.build_layout <layout.yaml> [--ink <inkscape.exe>]
14
+
15
+ layout YAML:
16
+ name / out
17
+ pages:
18
+ - page: {width_mm, height_mm, background}
19
+ mode: flow | grid | abs
20
+ grid: {cell_w_mm, cell_h_mm, cols?, label_w_mm, title, title_h_mm, enlarge}
21
+ gutters: {label_gap_mm, caption_gap_mm, col_gap_mm, row_gap_mm, margin_mm}
22
+ panels:
23
+ - {id, src, label?, caption?, row?(grid 行分组), x_mm/y_mm(abs), width_mm/height_mm(有意缩放)}
24
+
25
+ 实现要点(踩坑修正):
26
+ - 嵌入不用嵌套 <svg>(Inkscape 1.4 导 PDF 时每个嵌套 svg 变独立页),
27
+ 改深度合并: 子 SVG children 搬进 <g translate+scale>, id/url(#id)/href 加 "<pid>__" 前缀。
28
+ - 子 SVG 的 inkscape:page / sodipodi:namedview 多页标记必须丢弃。
29
+ - 根元素勿手写 xmlns(ET.register_namespace 已注册, 手写重复属性)。
30
+ """