marsilea 0.3.6__tar.gz → 0.4.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 (261) hide show
  1. {marsilea-0.3.6 → marsilea-0.4.0}/PKG-INFO +1 -1
  2. {marsilea-0.3.6 → marsilea-0.4.0}/pyproject.toml +11 -0
  3. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/__init__.py +1 -1
  4. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/base.py +7 -5
  5. marsilea-0.3.6/app/.gitignore +0 -2
  6. marsilea-0.3.6/app/.streamlit/pages.toml +0 -24
  7. marsilea-0.3.6/app/Dockerfile +0 -20
  8. marsilea-0.3.6/app/Home.py +0 -102
  9. marsilea-0.3.6/app/README.md +0 -17
  10. marsilea-0.3.6/app/components/__init__.py +0 -0
  11. marsilea-0.3.6/app/components/cmap_selector/__init__.py +0 -1
  12. marsilea-0.3.6/app/components/cmap_selector/selector.py +0 -176
  13. marsilea-0.3.6/app/components/data_input.py +0 -154
  14. marsilea-0.3.6/app/components/example_download.py +0 -71
  15. marsilea-0.3.6/app/components/initialize.py +0 -126
  16. marsilea-0.3.6/app/components/main_plots.py +0 -289
  17. marsilea-0.3.6/app/components/resource.py +0 -131
  18. marsilea-0.3.6/app/components/saver.py +0 -45
  19. marsilea-0.3.6/app/components/side_plots.py +0 -880
  20. marsilea-0.3.6/app/components/state.py +0 -158
  21. marsilea-0.3.6/app/components/transformation.py +0 -93
  22. marsilea-0.3.6/app/components/upset_example.csv +0 -1000
  23. marsilea-0.3.6/app/img/V1.mp4 +0 -0
  24. marsilea-0.3.6/app/img/V2.mp4 +0 -0
  25. marsilea-0.3.6/app/img/annolabels.png +0 -0
  26. marsilea-0.3.6/app/img/bar.png +0 -0
  27. marsilea-0.3.6/app/img/box.png +0 -0
  28. marsilea-0.3.6/app/img/boxen.png +0 -0
  29. marsilea-0.3.6/app/img/colors.png +0 -0
  30. marsilea-0.3.6/app/img/dendrogram.svg +0 -102
  31. marsilea-0.3.6/app/img/favicon.png +0 -0
  32. marsilea-0.3.6/app/img/favicon.svg +0 -61
  33. marsilea-0.3.6/app/img/heatmap.png +0 -0
  34. marsilea-0.3.6/app/img/heatmap.svg +0 -191
  35. marsilea-0.3.6/app/img/logo.png +0 -0
  36. marsilea-0.3.6/app/img/mark_map.png +0 -0
  37. marsilea-0.3.6/app/img/mark_map.svg +0 -112
  38. marsilea-0.3.6/app/img/point.png +0 -0
  39. marsilea-0.3.6/app/img/sized_heatmap.png +0 -0
  40. marsilea-0.3.6/app/img/sized_heatmap.svg +0 -357
  41. marsilea-0.3.6/app/img/sized_onlymap.png +0 -0
  42. marsilea-0.3.6/app/img/strip.png +0 -0
  43. marsilea-0.3.6/app/img/swarm.png +0 -0
  44. marsilea-0.3.6/app/img/violin.png +0 -0
  45. marsilea-0.3.6/app/img/x-layout.png +0 -0
  46. marsilea-0.3.6/app/pages/01 Simple_Heatmap.py +0 -243
  47. marsilea-0.3.6/app/pages/02 Cross-Layout_Heatmap.py +0 -239
  48. marsilea-0.3.6/app/pages/03 Upsetplot.py +0 -225
  49. marsilea-0.3.6/app/pages/04 Manual.py +0 -60
  50. marsilea-0.3.6/app/requirements.txt +0 -10
  51. marsilea-0.3.6/app/script/heatmap_data.py +0 -25
  52. marsilea-0.3.6/app/script/plot_layer_example_images.py +0 -32
  53. marsilea-0.3.6/app/script/plotter_example_images.py +0 -116
  54. marsilea-0.3.6/app/set_data_memberships.txt +0 -4
  55. marsilea-0.3.6/app/test.xlsx +0 -0
  56. marsilea-0.3.6/app/test_data/Stats_plot.txt +0 -10
  57. marsilea-0.3.6/app/test_data/example_data.txt +0 -20
  58. marsilea-0.3.6/app/test_data/number.txt +0 -20
  59. marsilea-0.3.6/app/test_data/row_labels.txt +0 -20
  60. marsilea-0.3.6/app/test_data/set_data_memberships.txt +0 -4
  61. marsilea-0.3.6/app/upset.xlsx +0 -0
  62. marsilea-0.3.6/data/IMDB.csv +0 -1000
  63. marsilea-0.3.6/data/PATIENT_DATA_oncoprint.tsv +0 -138
  64. marsilea-0.3.6/data/pbmc3k.h5ad +0 -0
  65. marsilea-0.3.6/docs/Makefile +0 -30
  66. marsilea-0.3.6/docs/README.md +0 -57
  67. marsilea-0.3.6/docs/examples/.gitignore +0 -2
  68. marsilea-0.3.6/docs/examples/Basics/README.rst +0 -2
  69. marsilea-0.3.6/docs/examples/Basics/plot_adv_heatmap.py +0 -25
  70. marsilea-0.3.6/docs/examples/Basics/plot_heatmap.py +0 -21
  71. marsilea-0.3.6/docs/examples/Basics/plot_stacked_bar.py +0 -44
  72. marsilea-0.3.6/docs/examples/Basics/plot_two_heatmap.py +0 -24
  73. marsilea-0.3.6/docs/examples/Gallery/README.rst +0 -4
  74. marsilea-0.3.6/docs/examples/Gallery/plot_arc_diagram.py +0 -77
  75. marsilea-0.3.6/docs/examples/Gallery/plot_available_plotters.py +0 -188
  76. marsilea-0.3.6/docs/examples/Gallery/plot_bivariate_dist.py +0 -94
  77. marsilea-0.3.6/docs/examples/Gallery/plot_mouse_embryo.py +0 -122
  78. marsilea-0.3.6/docs/examples/Gallery/plot_oil_well.py +0 -122
  79. marsilea-0.3.6/docs/examples/Gallery/plot_oncoprint.py +0 -124
  80. marsilea-0.3.6/docs/examples/Gallery/plot_pbmc3k.py +0 -99
  81. marsilea-0.3.6/docs/examples/Gallery/plot_sc_multiomics.py +0 -140
  82. marsilea-0.3.6/docs/examples/Gallery/plot_seqalign.py +0 -129
  83. marsilea-0.3.6/docs/examples/Gallery/plot_upset.py +0 -72
  84. marsilea-0.3.6/docs/examples/Plotters/README.rst +0 -4
  85. marsilea-0.3.6/docs/examples/Plotters/plot_anno_labels.py +0 -21
  86. marsilea-0.3.6/docs/examples/Plotters/plot_arc.py +0 -19
  87. marsilea-0.3.6/docs/examples/Plotters/plot_area.py +0 -18
  88. marsilea-0.3.6/docs/examples/Plotters/plot_bar.py +0 -18
  89. marsilea-0.3.6/docs/examples/Plotters/plot_box.py +0 -18
  90. marsilea-0.3.6/docs/examples/Plotters/plot_boxen.py +0 -18
  91. marsilea-0.3.6/docs/examples/Plotters/plot_center_bar.py +0 -19
  92. marsilea-0.3.6/docs/examples/Plotters/plot_chunk.py +0 -20
  93. marsilea-0.3.6/docs/examples/Plotters/plot_color_mesh.py +0 -20
  94. marsilea-0.3.6/docs/examples/Plotters/plot_colors.py +0 -20
  95. marsilea-0.3.6/docs/examples/Plotters/plot_fixed_chunk.py +0 -28
  96. marsilea-0.3.6/docs/examples/Plotters/plot_labels.py +0 -20
  97. marsilea-0.3.6/docs/examples/Plotters/plot_marker_mesh.py +0 -19
  98. marsilea-0.3.6/docs/examples/Plotters/plot_numbers.py +0 -17
  99. marsilea-0.3.6/docs/examples/Plotters/plot_point.py +0 -18
  100. marsilea-0.3.6/docs/examples/Plotters/plot_seq_logo.py +0 -20
  101. marsilea-0.3.6/docs/examples/Plotters/plot_sized_mesh.py +0 -18
  102. marsilea-0.3.6/docs/examples/Plotters/plot_stack_bar.py +0 -19
  103. marsilea-0.3.6/docs/examples/Plotters/plot_strip.py +0 -18
  104. marsilea-0.3.6/docs/examples/Plotters/plot_swarm.py +0 -18
  105. marsilea-0.3.6/docs/examples/Plotters/plot_text_mesh.py +0 -19
  106. marsilea-0.3.6/docs/examples/Plotters/plot_title.py +0 -20
  107. marsilea-0.3.6/docs/examples/Plotters/plot_violin.py +0 -18
  108. marsilea-0.3.6/docs/examples/README.rst +0 -2
  109. marsilea-0.3.6/docs/how_to/README.rst +0 -4
  110. marsilea-0.3.6/docs/how_to/customization/README.rst +0 -8
  111. marsilea-0.3.6/docs/how_to/customization/plot_add_border.py +0 -31
  112. marsilea-0.3.6/docs/how_to/customization/plot_get_axes.py +0 -42
  113. marsilea-0.3.6/docs/how_to/dendrogram/README.rst +0 -2
  114. marsilea-0.3.6/docs/how_to/dendrogram/plot_color_dendrogram.py +0 -31
  115. marsilea-0.3.6/docs/how_to/dendrogram/plot_dendrogram_control.py +0 -19
  116. marsilea-0.3.6/docs/how_to/layout/README.rst +0 -3
  117. marsilea-0.3.6/docs/how_to/layout/plot_adjust_figure_size.py +0 -58
  118. marsilea-0.3.6/docs/how_to/layout/plot_labeling.py +0 -45
  119. marsilea-0.3.6/docs/how_to/layout/plot_margin.py +0 -28
  120. marsilea-0.3.6/docs/how_to/legends/README.rst +0 -7
  121. marsilea-0.3.6/docs/how_to/legends/plot_disable_legend.py +0 -29
  122. marsilea-0.3.6/docs/how_to/legends/plot_legends.py +0 -23
  123. marsilea-0.3.6/docs/how_to/save/README.rst +0 -5
  124. marsilea-0.3.6/docs/how_to/save/plot.pdf +0 -0
  125. marsilea-0.3.6/docs/how_to/save/plot.png +0 -0
  126. marsilea-0.3.6/docs/how_to/save/plot_save.py +0 -29
  127. marsilea-0.3.6/docs/make.bat +0 -35
  128. marsilea-0.3.6/docs/requirements.txt +0 -10
  129. marsilea-0.3.6/docs/source/.gitignore +0 -4
  130. marsilea-0.3.6/docs/source/_static/css/custom.css +0 -57
  131. marsilea-0.3.6/docs/source/_templates/autosummary.rst +0 -15
  132. marsilea-0.3.6/docs/source/api/index.rst +0 -308
  133. marsilea-0.3.6/docs/source/conf.py +0 -163
  134. marsilea-0.3.6/docs/source/img/code_example.png +0 -0
  135. marsilea-0.3.6/docs/source/img/cover.png +0 -0
  136. marsilea-0.3.6/docs/source/img/marsilea-renderplan-logic.drawio.svg +0 -4
  137. marsilea-0.3.6/docs/source/index.rst +0 -97
  138. marsilea-0.3.6/docs/source/installation.rst +0 -14
  139. marsilea-0.3.6/docs/source/sg_execution_times.rst +0 -175
  140. marsilea-0.3.6/docs/source/tutorial/axes-level.rst +0 -73
  141. marsilea-0.3.6/docs/source/tutorial/concatenation.rst +0 -90
  142. marsilea-0.3.6/docs/source/tutorial/heatmap.rst +0 -187
  143. marsilea-0.3.6/docs/source/tutorial/index.rst +0 -142
  144. marsilea-0.3.6/docs/source/tutorial/intro.rst +0 -181
  145. marsilea-0.3.6/docs/source/tutorial/intro2.rst +0 -146
  146. marsilea-0.3.6/docs/source/tutorial/new_renderplan.rst +0 -162
  147. marsilea-0.3.6/docs/source/tutorial/upset.rst +0 -125
  148. marsilea-0.3.6/img/Logo(1).zip +0 -0
  149. marsilea-0.3.6/img/Logo.zip +0 -0
  150. marsilea-0.3.6/img/banner-blue.jpg +0 -0
  151. marsilea-0.3.6/img/banner-dark-gradient.jpg +0 -0
  152. marsilea-0.3.6/img/banner-dark.jpg +0 -0
  153. marsilea-0.3.6/img/banner-rice-white.jpg +0 -0
  154. marsilea-0.3.6/img/banner-white.jpg +0 -0
  155. marsilea-0.3.6/img/logo/Logo/.DS_Store +0 -0
  156. marsilea-0.3.6/img/logo/Logo/Logo.svg +0 -27
  157. marsilea-0.3.6/img/logo/Logo/logo.png +0 -0
  158. marsilea-0.3.6/img/logo/Logo//346/265/205/350/223/235/346/270/220/345/217/230.jpg +0 -0
  159. marsilea-0.3.6/img/logo/Logo//346/267/261/350/211/262/350/203/214/346/231/257.jpg +0 -0
  160. marsilea-0.3.6/img/logo/Logo//347/261/263/350/211/262.jpg +0 -0
  161. marsilea-0.3.6/img/logo/Logo//347/272/257/347/231/275.jpg +0 -0
  162. marsilea-0.3.6/img/logo/Logo//350/247/222/345/272/246/346/270/220/345/217/230.jpg +0 -0
  163. marsilea-0.3.6/img/logo/__MACOSX/Logo/._.DS_Store +0 -0
  164. marsilea-0.3.6/img/logo.png +0 -0
  165. marsilea-0.3.6/img/logo.svg +0 -27
  166. marsilea-0.3.6/img/publication/API-interface.png +0 -0
  167. marsilea-0.3.6/img/publication/Snap-1.png +0 -0
  168. marsilea-0.3.6/img/publication/Snap-2.png +0 -0
  169. marsilea-0.3.6/img/publication/Snap-3.png +0 -0
  170. marsilea-0.3.6/img/publication/Stacked bar.png +0 -0
  171. marsilea-0.3.6/img/publication/bivar_kde.png +0 -0
  172. marsilea-0.3.6/img/publication/layout-basic-change-canvas-size-code.png +0 -0
  173. marsilea-0.3.6/img/publication/layout-basic-change-canvas-size.png +0 -0
  174. marsilea-0.3.6/img/publication/layout-basic-change-location-code.png +0 -0
  175. marsilea-0.3.6/img/publication/layout-basic-change-location.png +0 -0
  176. marsilea-0.3.6/img/publication/layout-basic-change-pad-code.png +0 -0
  177. marsilea-0.3.6/img/publication/layout-basic-change-pad.png +0 -0
  178. marsilea-0.3.6/img/publication/layout-basic-change-plotter-size-code.png +0 -0
  179. marsilea-0.3.6/img/publication/layout-basic-change-plotter-size.png +0 -0
  180. marsilea-0.3.6/img/publication/layout-basic-change-plotter-type-code.png +0 -0
  181. marsilea-0.3.6/img/publication/layout-basic-change-plotter-type.png +0 -0
  182. marsilea-0.3.6/img/publication/layout-basic-code.png +0 -0
  183. marsilea-0.3.6/img/publication/layout-basic.png +0 -0
  184. marsilea-0.3.6/img/publication/layout-skeleton-step1.png +0 -0
  185. marsilea-0.3.6/img/publication/layout-skeleton-step2.png +0 -0
  186. marsilea-0.3.6/img/publication/layout-skeleton-step3.png +0 -0
  187. marsilea-0.3.6/img/publication/layout-skeleton-step4.png +0 -0
  188. marsilea-0.3.6/img/publication/layout-step-1a-code.png +0 -0
  189. marsilea-0.3.6/img/publication/layout-step-1a.png +0 -0
  190. marsilea-0.3.6/img/publication/layout-step-1b-code.png +0 -0
  191. marsilea-0.3.6/img/publication/layout-step-1b.png +0 -0
  192. marsilea-0.3.6/img/publication/layout-step-2-code.png +0 -0
  193. marsilea-0.3.6/img/publication/layout-step-2.png +0 -0
  194. marsilea-0.3.6/img/publication/layout-step-3-code.png +0 -0
  195. marsilea-0.3.6/img/publication/layout-step-3.png +0 -0
  196. marsilea-0.3.6/img/publication/layout-step-4-code.png +0 -0
  197. marsilea-0.3.6/img/publication/layout-step-4.png +0 -0
  198. marsilea-0.3.6/img/publication/oncoprint.png +0 -0
  199. marsilea-0.3.6/img/publication/upset.png +0 -0
  200. marsilea-0.3.6/img/publication/web-app-screenshot-1.png +0 -0
  201. marsilea-0.3.6/img/publication/web-app-screenshot-2.png +0 -0
  202. marsilea-0.3.6/readthedocs.yaml +0 -12
  203. marsilea-0.3.6/scripts/benchmark/marsilea/marsilea_cooking_oils_base.py +0 -97
  204. marsilea-0.3.6/scripts/benchmark/marsilea/marsilea_cooking_oils_v1.py +0 -105
  205. marsilea-0.3.6/scripts/benchmark/marsilea/marsilea_cooking_oils_v2.py +0 -118
  206. marsilea-0.3.6/scripts/benchmark/marsilea_vs_matplotlib.png +0 -0
  207. marsilea-0.3.6/scripts/benchmark/marsilea_vs_matplotlib.svg +0 -1846
  208. marsilea-0.3.6/scripts/benchmark/matplotlib/matplotlib_cooking_oils_base.py +0 -180
  209. marsilea-0.3.6/scripts/benchmark/matplotlib/matplotlib_cooking_oils_v1.py +0 -230
  210. marsilea-0.3.6/scripts/benchmark/matplotlib/matplotlib_cooking_oils_v2.py +0 -220
  211. marsilea-0.3.6/scripts/benchmark/result.py +0 -168
  212. marsilea-0.3.6/scripts/example_figures/arc-diagrams.py +0 -164
  213. marsilea-0.3.6/scripts/example_figures/cooking_oils.py +0 -122
  214. marsilea-0.3.6/scripts/example_figures/mouse_map.py +0 -157
  215. marsilea-0.3.6/scripts/example_figures/msa.py +0 -148
  216. marsilea-0.3.6/scripts/example_figures/oncoprint.py +0 -143
  217. marsilea-0.3.6/scripts/example_figures/single-heatmap.py +0 -101
  218. marsilea-0.3.6/scripts/example_figures/tracks.py +0 -141
  219. marsilea-0.3.6/scripts/example_figures/two-heatmap.py +0 -141
  220. marsilea-0.3.6/scripts/example_figures/upset.py +0 -56
  221. marsilea-0.3.6/scripts/example_figures/violin_swarm.py +0 -71
  222. marsilea-0.3.6/scripts/publication/arc_diagram.svg +0 -5974
  223. marsilea-0.3.6/scripts/publication/bivariate_dist.svg +0 -32
  224. marsilea-0.3.6/scripts/publication/mouse_embryo.svg +0 -168201
  225. marsilea-0.3.6/tests/test_data_input.py +0 -63
  226. marsilea-0.3.6/tests/test_deform.py +0 -92
  227. marsilea-0.3.6/tests/test_mesh.py +0 -30
  228. {marsilea-0.3.6 → marsilea-0.4.0}/.github/workflows/build.yaml +0 -0
  229. {marsilea-0.3.6 → marsilea-0.4.0}/.github/workflows/deploy_streamlit.yaml +0 -0
  230. {marsilea-0.3.6 → marsilea-0.4.0}/.github/workflows/lint.yaml +0 -0
  231. {marsilea-0.3.6 → marsilea-0.4.0}/.gitignore +0 -0
  232. {marsilea-0.3.6 → marsilea-0.4.0}/.streamlit/config.toml +0 -0
  233. {marsilea-0.3.6 → marsilea-0.4.0}/CITATION.cff +0 -0
  234. {marsilea-0.3.6 → marsilea-0.4.0}/CODE_OF_CONDUCT.md +0 -0
  235. {marsilea-0.3.6 → marsilea-0.4.0}/LICENSE +0 -0
  236. {marsilea-0.3.6 → marsilea-0.4.0}/README.md +0 -0
  237. {marsilea-0.3.6 → marsilea-0.4.0}/setup.py +0 -0
  238. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/_api.py +0 -0
  239. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/_deform.py +0 -0
  240. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/dataset.py +0 -0
  241. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/dendrogram.py +0 -0
  242. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/exceptions.py +0 -0
  243. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/heatmap.py +0 -0
  244. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/layers.py +0 -0
  245. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/layout.py +0 -0
  246. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/__init__.py +0 -0
  247. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/_images.py +0 -0
  248. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/_seaborn.py +0 -0
  249. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/_utils.py +0 -0
  250. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/arc.py +0 -0
  251. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/area.py +0 -0
  252. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/bar.py +0 -0
  253. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/base.py +0 -0
  254. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/bio.py +0 -0
  255. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/mesh.py +0 -0
  256. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/plotter/text.py +0 -0
  257. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/upset.py +0 -0
  258. {marsilea-0.3.6 → marsilea-0.4.0}/src/marsilea/utils.py +0 -0
  259. {marsilea-0.3.6 → marsilea-0.4.0}/src/oncoprinter/__init__.py +0 -0
  260. {marsilea-0.3.6 → marsilea-0.4.0}/src/oncoprinter/core.py +0 -0
  261. {marsilea-0.3.6 → marsilea-0.4.0}/src/oncoprinter/preset.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: marsilea
3
- Version: 0.3.6
3
+ Version: 0.4.0
4
4
  Summary: Declarative creation of composable visualization
5
5
  Author: Zhihang Zheng
6
6
  Author-email: Mr-Milk <yzheng@cemm.at>
@@ -44,5 +44,16 @@ dev = [
44
44
  "mpl_fontkit"
45
45
  ]
46
46
 
47
+ [tool.flit.sdist]
48
+ exclude = [
49
+ "docs",
50
+ "app",
51
+ "data",
52
+ "img",
53
+ "tests",
54
+ "scripts",
55
+ "readthedocs.yaml",
56
+ ]
57
+
47
58
  [tool.ruff.lint.per-file-ignores]
48
59
  "__init__.py" = ["F401"]
@@ -1,6 +1,6 @@
1
1
  """Declarative creation of composable visualization"""
2
2
 
3
- __version__ = "0.3.6"
3
+ __version__ = "0.4.0"
4
4
 
5
5
  import marsilea.plotter as plotter
6
6
  from ._deform import Deformation
@@ -67,21 +67,22 @@ class LegendMaker:
67
67
  """
68
68
  raise NotImplementedError("Should be implemented in derived class")
69
69
 
70
- def custom_legend(self, legend, name=None):
70
+ def custom_legend(self, legend_func, name=None):
71
71
  """Add a custom legend
72
72
 
73
73
  Parameters
74
74
  ----------
75
75
 
76
- legend : `Artist <matplotlib.artist.Artists>`
77
- A legend object
76
+ legend_func : Callable
77
+ A function that return the legend object,
78
+ the legend must be an `Artist <matplotlib.artist.Artists>`
78
79
  name : str, optional
79
80
  The name of the legend
80
81
 
81
82
  """
82
83
  if name is None:
83
84
  name = str(uuid4())
84
- self._user_legends[name] = [legend]
85
+ self._user_legends[name] = legend_func
85
86
 
86
87
  def add_legends(
87
88
  self,
@@ -159,7 +160,8 @@ class LegendMaker:
159
160
  self.layout.remove_legend_ax()
160
161
 
161
162
  def _legends_drawer(self, ax):
162
- legends = {**self.get_legends(), **self._user_legends}
163
+ user_legends = {k: [v()] for k, v in self._user_legends.items()}
164
+ legends = {**self.get_legends(), **user_legends}
163
165
 
164
166
  # force to remove all legends before drawing
165
167
  # In case some legends are added implicitly
@@ -1,2 +0,0 @@
1
- .fonts
2
- *.xlsx
@@ -1,24 +0,0 @@
1
- [[pages]]
2
- path = "index.py"
3
- name = "Home"
4
- icon = "🏠"
5
-
6
- #[[pages]]
7
- #path = "other_pages/page2.py"
8
- #name = "Page 2"
9
- #icon = ":books:"
10
- #
11
- #[[pages]]
12
- #name = "My second"
13
- #icon = "🎈️"
14
- #is_section = true
15
- #
16
- ## Pages after an `is_section = true` will be indented
17
- #[[pages]]
18
- #name = "Another page"
19
- #icon = "💪"
20
- #
21
- ## Unless you explicitly say in_section = false`
22
- #[[pages]]
23
- #name = "Not in a section"
24
- #in_section = false
@@ -1,20 +0,0 @@
1
- # Use the official Python image as the base image
2
- FROM python:3.10
3
-
4
- # Set the working directory in the container
5
- WORKDIR /app
6
-
7
- # Copy the requirements.txt file into the container
8
- COPY requirements.txt .
9
-
10
- # Install any dependencies
11
- RUN pip install --no-cache-dir -r requirements.txt
12
-
13
- # Copy the content of the local src directory to the working directory
14
- COPY . .
15
-
16
- # Expose the port that Streamlit will run on
17
- EXPOSE 8501
18
-
19
- # Command to run the application when the container starts
20
- CMD ["streamlit", "run", "Home.py", "--server.port=8501", "--server.address=0.0.0.0"]
@@ -1,102 +0,0 @@
1
- import streamlit as st
2
- from components.initialize import init_page, inject_css
3
-
4
- init_page("Marsilea")
5
- inject_css()
6
-
7
- banner, title = st.columns([1, 1.5])
8
- with banner:
9
- st.markdown(
10
- '<video controls width="250" autoplay="true" muted="true" '
11
- 'loop="true" playsinline style="pointer-events: none;">'
12
- '<source src="https://raw.githubusercontent.com/Marsilea-viz/'
13
- 'marsilea/main/app/img/V1.mp4" '
14
- 'type="video/mp4" /></video>',
15
- unsafe_allow_html=True,
16
- )
17
-
18
- with title:
19
- st.title("Marsilea")
20
- st.subheader("Create :blue[composable] visualization")
21
- st.text("")
22
- st.markdown(
23
- "*By [Mr.Milk](https://github.com/Mr-Milk) and "
24
- "[Squirtle692](https://github.com/Squirtle692)*"
25
- )
26
-
27
- st.markdown("---")
28
-
29
- st.subheader("About")
30
- st.markdown(
31
- "Marsilea is a tool for you to create composable visualization. "
32
- "A single-plot visualization can be combined with other plots to capture"
33
- "the full picture of your data."
34
- )
35
-
36
- st.markdown("---")
37
-
38
- st.subheader("Online Toolbox")
39
- st.text("")
40
- t1, t2, t3 = st.columns(3)
41
-
42
-
43
- def tools(name, img, page, size=150):
44
- st.markdown(
45
- f'<div style="display: flex; justify-content: center; '
46
- f'align-items: center; flex-direction: column;">'
47
- f'<p style="font-weight: 600;">{name}</p>'
48
- f'<a target="_self" href="{page}">'
49
- f'<img style="width: {size}px;" src="{img}"></a>'
50
- f"</div>",
51
- unsafe_allow_html=True,
52
- )
53
-
54
-
55
- with t1:
56
- tools(
57
- "Simple Heatmap",
58
- "https://marsilea.readthedocs.io/en/latest/" "_images/concatenation-1.png",
59
- page="/Simple_Heatmap",
60
- size=130,
61
- )
62
-
63
- with t2:
64
- tools(
65
- "Complex Heatmap",
66
- "https://marsilea.readthedocs.io/en/latest/"
67
- "_images/sphx_glr_plot_pbmc3k_thumb.png",
68
- page="X-Layout_Heatmap",
69
- size=200,
70
- )
71
-
72
- with t3:
73
- tools(
74
- "Upset Plot",
75
- "https://marsilea.readthedocs.io/en/latest/"
76
- "_images/sphx_glr_plot_upset_thumb.png",
77
- page="/Upsetplot",
78
- size=220,
79
- )
80
-
81
- st.markdown("---")
82
-
83
-
84
- st.subheader("Python Package")
85
- s1, s2, s3 = st.columns([1, 4, 5])
86
- with s1:
87
- st.image(
88
- "https://cdn3.iconfinder.com/data/icons/logos-and-brands-adobe/512/267_Python-512.png",
89
- width=50,
90
- )
91
-
92
- with s2:
93
- st.markdown(
94
- "Familiar with Python? Try our Python package "
95
- "that can be easily integrated into your data pipeline!"
96
- )
97
- with s3:
98
- st.code("pip install marsilea", language="bash")
99
-
100
- st.markdown("---")
101
-
102
- st.markdown("Copyright © 2024 [Marsilea](https://github.com/Marsilea-viz)")
@@ -1,17 +0,0 @@
1
- # How to run the app version of Marsilea
2
-
3
- ## Using Docker
4
-
5
- ### Step 1: Build the image
6
-
7
- ```bash
8
- docker build -t marsilea-app .
9
- ```
10
-
11
- ### Step 2: Run the container
12
-
13
- ```bash
14
- docker run -p 8501:8501 marsilea-app
15
- ```
16
-
17
- Go to http://localhost:8501 to see the app.
File without changes
@@ -1 +0,0 @@
1
- from .selector import ColormapSelector
@@ -1,176 +0,0 @@
1
- import matplotlib as mpl
2
- import matplotlib.pyplot as plt
3
- import numpy as np
4
- import streamlit as st
5
- from matplotlib.cm import get_cmap
6
- from matplotlib.colors import (
7
- LinearSegmentedColormap,
8
- Normalize,
9
- CenteredNorm,
10
- TwoSlopeNorm,
11
- )
12
-
13
-
14
- @st.cache_data
15
- def get_colormap_names():
16
- cmap_mapper = {}
17
- for i in mpl.colormaps:
18
- if not i.endswith("_r"):
19
- cmap_name = i
20
- cmap_mapper[i] = cmap_name.capitalize()
21
- return cmap_mapper
22
-
23
-
24
- def get_colormap_images(cmap):
25
- gradient = np.linspace(0, 1, 256)
26
- gradient = np.vstack((gradient, gradient))
27
-
28
- fig = plt.figure(figsize=(6, 0.5), dpi=90)
29
- ax = fig.add_axes([0, 0, 1, 1])
30
- ax.imshow(gradient, aspect="auto", cmap=cmap)
31
- ax.set_axis_off()
32
- plt.close(fig)
33
- return fig
34
-
35
-
36
- def random_color():
37
- return "#" + "".join(np.random.choice(list("0123456789ABCDEF"), 6))
38
-
39
-
40
- class ColormapSelector:
41
- def __init__(self, key, default="coolwarm", data_mapping=True):
42
- cmap_data = get_colormap_names()
43
- cmap_options = sorted(cmap_data.keys())
44
- default_index = cmap_options.index(default)
45
- self.reverse = False
46
-
47
- st.markdown("**Colormap**")
48
-
49
- radio_box, rev_box = st.columns(2)
50
-
51
- with radio_box:
52
- input_cmap = st.radio(
53
- label="cmap_input",
54
- label_visibility="collapsed",
55
- options=["Preset", "Create New"],
56
- horizontal=True,
57
- key=f"{key}-input-cmap",
58
- )
59
- with rev_box:
60
- self.reverse = st.checkbox("Reverse colormap", key=f"{key}-rev-cmap")
61
-
62
- if input_cmap == "Preset":
63
- color_box, cmap_box = st.columns(2)
64
- with color_box:
65
- cmap = st.selectbox(
66
- "Select Preset Colormap",
67
- label_visibility="collapsed",
68
- key=f"{key}-preset-cmap",
69
- options=cmap_options,
70
- index=default_index,
71
- format_func=lambda v: cmap_data[v],
72
- help="The preset colormap are illuminated "
73
- "compensated for best visual effect",
74
- )
75
- cmap = get_cmap(cmap)
76
- if self.reverse:
77
- cmap = cmap.reversed()
78
- self.cmap = cmap
79
- with cmap_box:
80
- cmap_fig = get_colormap_images(self.cmap)
81
- st.pyplot(cmap_fig)
82
- else:
83
- select_box, cmap_box = st.columns(2)
84
- with select_box:
85
- ncolors = st.selectbox(
86
- label="Colormap Type",
87
- key=f"{key}-select-gradient",
88
- label_visibility="collapsed",
89
- options=["One Gradient", "Two Gradient"],
90
- )
91
- _, c_lower, c_center, c_upper = st.columns([4, 1, 1, 1])
92
- with c_lower:
93
- lower = st.color_picker(
94
- label="Lower",
95
- value="#CB1B45",
96
- key=f"{key}-lower-cmap-2",
97
- )
98
- with c_upper:
99
- upper = st.color_picker(
100
- label="Upper",
101
- value="#7B90D2",
102
- key=f"{key}-upper-cmap-2",
103
- )
104
-
105
- if ncolors == "One Gradient":
106
- colors = [lower, upper]
107
- else:
108
- with c_center:
109
- center = st.color_picker(
110
- label="Center",
111
- value="#BDC0BA",
112
- key=f"{key}-center-cmap-3",
113
- )
114
- colors = [lower, center, upper]
115
- self.cmap = LinearSegmentedColormap.from_list("user_cmap", colors)
116
-
117
- if self.reverse:
118
- self.cmap = self.cmap.reversed()
119
-
120
- with cmap_box:
121
- cmap_fig = get_colormap_images(self.cmap)
122
- st.pyplot(cmap_fig)
123
-
124
- if data_mapping:
125
- norm_strategy = st.selectbox(
126
- "Mapping Strategy",
127
- key=f"{key}-norm-selector",
128
- options=["Linear", "Min-Max", "Centered On", "Two Range"],
129
- )
130
- self.norm = None
131
- if norm_strategy == "Min-Max":
132
- st.caption("Value outside the min/max will be mapped to min/max")
133
- v1, v2 = st.columns(2)
134
- with v1:
135
- vmin = st.number_input("Min", key=f"{key}-norm-vmin")
136
- with v2:
137
- vmax = st.number_input("Max", key=f"{key}-norm-vmax")
138
- self.norm = Normalize(vmin=vmin, vmax=vmax)
139
- elif norm_strategy == "Centered On":
140
- st.caption("Center on a specific value and extend symmetrically")
141
- v1, v2 = st.columns(2)
142
- with v1:
143
- vcenter = st.number_input(
144
- "Center", key=f"{key}-center_norm-vcenter"
145
- )
146
- with v2:
147
- vhalf = st.number_input(
148
- "Extend",
149
- min_value=0.0,
150
- value=1.0,
151
- key=f"{key}-center_norm-vhalf",
152
- )
153
- self.norm = CenteredNorm(vcenter=vcenter, halfrange=vhalf)
154
- elif norm_strategy == "Two Range":
155
- st.caption("Map to two range")
156
- v1, v2, v3 = st.columns(3)
157
- with v1:
158
- vmin = st.number_input("Min", value=0.0, key=f"{key}-tsnorm-vmin")
159
- with v2:
160
- vcenter = st.number_input(
161
- "Center", value=vmin + 1, key=f"{key}-tsnorm-vcenter"
162
- )
163
- with v3:
164
- vmax = st.number_input(
165
- "Max", value=vcenter + 1, key=f"{key}-tsnorm-vmax"
166
- )
167
- if not ((vmin < vcenter) and (vcenter < vmax)):
168
- st.error("Min, Center, Max must be ascending.", icon="📉")
169
- else:
170
- self.norm = TwoSlopeNorm(vcenter=vcenter, vmin=vmin, vmax=vmax)
171
-
172
- def get_cmap(self):
173
- return self.cmap
174
-
175
- def get_norm(self):
176
- return self.norm
@@ -1,154 +0,0 @@
1
- from pathlib import Path
2
- from typing import Any
3
-
4
- import numpy as np
5
- import pandas as pd
6
- import streamlit as st
7
-
8
- from openpyxl import load_workbook
9
-
10
-
11
- class InputBase:
12
- sep: str
13
- user_input: Any
14
-
15
- def __init__(self, key=None):
16
- self.key = f"{self.__class__.__name__}-{key}"
17
-
18
- def parse(self):
19
- pass
20
-
21
- def seperator(self):
22
- sep_options = {"Tab (\\t)": "\t", "Comma (,)": ",", "Space (' ')": " "}
23
- user_sep = st.selectbox("Seperator", key=self.key, options=sep_options.keys())
24
- self.sep = sep_options[user_sep]
25
-
26
-
27
- @st.cache_data
28
- def parse_file(file, header=False, index=False, sheet_name=0):
29
- index_col = None if not index else 0
30
- suffix = file.name.split(".")[-1]
31
- if suffix in ["csv", "txt", "tsv"]:
32
- header = None if not header else "infer"
33
- reader = pd.read_csv
34
- sep = "," if suffix == "csv" else "\t"
35
- kws = dict(sep=sep, header=header, index_col=index_col)
36
- else:
37
- header = None if not header else 0
38
- reader = pd.read_excel
39
- kws = dict(header=header, index_col=index_col, sheet_name=sheet_name)
40
- data = reader(file, **kws)
41
- return data
42
-
43
-
44
- class FileUpload(InputBase):
45
- def __init__(
46
- self, key=None, header=False, index=False, use_header=False, use_index=False
47
- ):
48
- super().__init__(key=key)
49
- self.header = use_header
50
- self.index = use_index
51
- self.user_input = st.file_uploader(
52
- "Choose a table file",
53
- key=f"table_reader-{self.key}",
54
- accept_multiple_files=False,
55
- label_visibility="collapsed",
56
- type=["txt", "csv", "xlsx"],
57
- )
58
-
59
- if index & header:
60
- h1, h2 = st.columns(2)
61
- with h1:
62
- self.header = self._header_checkbox()
63
- with h2:
64
- self.index = self._index_checkbox()
65
-
66
- elif header:
67
- self.header = self._header_checkbox()
68
-
69
- elif index:
70
- self.index = self._index_checkbox()
71
-
72
- self.sheet_name = 0
73
- if self.user_input is not None:
74
- suffix = self.user_input.name.split(".")[-1]
75
- if suffix == "xlsx":
76
- wb = load_workbook(self.user_input, read_only=True, keep_links=False)
77
- sheetnames = wb.sheetnames
78
- if len(sheetnames) > 1:
79
- self.sheet_name = st.selectbox(
80
- "Please select a sheet", options=sheetnames
81
- )
82
-
83
- def _header_checkbox(self):
84
- return st.checkbox(
85
- "Use first row as header?",
86
- value=self.header,
87
- key=f"select-header-{self.key}",
88
- )
89
-
90
- def _index_checkbox(self):
91
- return st.checkbox(
92
- "Use first column as row labels?",
93
- value=self.index,
94
- key=f"select-index-{self.key}",
95
- )
96
-
97
- def _parse_to_df(self):
98
- if self.user_input is not None:
99
- return parse_file(
100
- self.user_input,
101
- header=self.header,
102
- index=self.index,
103
- sheet_name=self.sheet_name,
104
- )
105
-
106
- def parse(self) -> np.ndarray:
107
- if self.user_input is not None:
108
- data = self._parse_to_df()
109
- if len(data.columns) == 1:
110
- return data.to_numpy().flatten()
111
- return data.to_numpy()
112
-
113
- def parse_parts(self, row_label=True, col_label=True):
114
- if self.user_input is not None:
115
- data = parse_file(
116
- self.user_input,
117
- header=col_label,
118
- index=row_label,
119
- sheet_name=self.sheet_name,
120
- )
121
- row = data.index.to_numpy(dtype=str)
122
- col = data.columns.to_numpy(dtype=str)
123
- data = data.to_numpy()
124
- return data, row, col
125
-
126
- def parse_dataframe(self) -> pd.DataFrame:
127
- return self._parse_to_df()
128
-
129
- @property
130
- def name(self):
131
- if self.user_input is None:
132
- return ""
133
- else:
134
- return Path(self.user_input.name).stem
135
-
136
-
137
- class PasteText(InputBase):
138
- def __init__(self, cast_number=True, key=None):
139
- super().__init__(key=key)
140
- self.cast_number = cast_number
141
- self.user_input = st.text_area("Paste data here", key=self.key)
142
- self.seperator()
143
-
144
- def parse(self):
145
- if len(self.user_input) > 0:
146
- rows = self.user_input.strip().split("\n")
147
- raw_data = [row.split(self.sep) for row in rows]
148
- try:
149
- data = np.array(raw_data)
150
- if self.cast_number:
151
- data = data.astype(float)
152
- return pd.DataFrame(data)
153
- except Exception:
154
- st.error("Your seperator seems incorrect")
@@ -1,71 +0,0 @@
1
- import base64
2
- import io
3
- import zipfile
4
-
5
- import numpy as np
6
- import pandas as pd
7
- import streamlit as st
8
- from random_word.random_word import RandomWords
9
-
10
-
11
- class ExampleDataGenerator:
12
- def __init__(self, col, row):
13
- np.random.seed(0)
14
- self.col = col
15
- self.row = row
16
- self.words = RandomWords()
17
- self.export_kws = dict(sep="\t", index=False, header=None)
18
-
19
- def matrix(self):
20
- return np.random.randint(0, 101, (self.row, self.col))
21
-
22
- def col_labels(self):
23
- labels = [self.words.get_random_word() for _ in range(self.col)]
24
- return np.array(labels)
25
-
26
- def row_labels(self):
27
- labels = [self.words.get_random_word() for _ in range(self.row)]
28
- return np.array(labels)
29
-
30
- def stats_data(self):
31
- return np.random.randn(10, self.row)
32
-
33
- def numbers(self):
34
- return np.random.randint(10, 100, self.row)
35
-
36
- def get_text(self, data):
37
- return pd.DataFrame(data=data).to_csv(**self.export_kws)
38
-
39
- def to_zip(self):
40
- zip_buffer = io.BytesIO()
41
- with zipfile.ZipFile(zip_buffer, "a") as z:
42
- z.writestr("matrix_data.txt", self.get_text(self.matrix()))
43
- z.writestr("labels (row).txt", self.get_text(self.row_labels()))
44
- z.writestr("labels (col).txt", self.get_text(self.col_labels()))
45
- z.writestr("statistic plot.txt", self.get_text(self.stats_data()))
46
- z.writestr("numbers.txt", self.get_text(self.numbers()))
47
- return zip_buffer
48
-
49
- def to_base64(self):
50
- zip_bytes = self.to_zip()
51
- return base64.b64encode(zip_bytes.getvalue()).decode()
52
-
53
-
54
- @st.cache_resource
55
- def get_base64():
56
- g = ExampleDataGenerator(20, 20)
57
- return g.to_base64()
58
-
59
-
60
- class ExampleDownloader:
61
- def __init__(self):
62
- self.b64 = get_base64()
63
- href = (
64
- f'<a href="data:file/zip;base64,{self.b64}" '
65
- f'download="example.zip">Example Data</a>'
66
- )
67
- st.markdown(href, unsafe_allow_html=True)
68
-
69
-
70
- if __name__ == "__main__":
71
- g = ExampleDataGenerator(20, 20)