marsilea 0.4.7__tar.gz → 0.5.0rc1__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 (33) hide show
  1. {marsilea-0.4.7 → marsilea-0.5.0rc1}/PKG-INFO +17 -17
  2. {marsilea-0.4.7 → marsilea-0.5.0rc1}/README.md +11 -0
  3. {marsilea-0.4.7 → marsilea-0.5.0rc1}/pyproject.toml +33 -21
  4. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/__init__.py +1 -1
  5. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/base.py +7 -0
  6. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/heatmap.py +6 -3
  7. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/arc.py +2 -4
  8. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/area.py +1 -2
  9. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/bar.py +1 -2
  10. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/bio.py +3 -6
  11. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/range.py +1 -2
  12. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/upset.py +1 -1
  13. {marsilea-0.4.7 → marsilea-0.5.0rc1}/.gitignore +0 -0
  14. {marsilea-0.4.7 → marsilea-0.5.0rc1}/LICENSE +0 -0
  15. {marsilea-0.4.7 → marsilea-0.5.0rc1}/setup.py +0 -0
  16. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/_api.py +0 -0
  17. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/_deform.py +0 -0
  18. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/dataset.py +0 -0
  19. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/dendrogram.py +0 -0
  20. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/exceptions.py +0 -0
  21. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/layers.py +0 -0
  22. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/layout.py +0 -0
  23. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/__init__.py +0 -0
  24. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/_seaborn.py +0 -0
  25. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/_utils.py +0 -0
  26. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/base.py +0 -0
  27. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/images.py +0 -0
  28. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/mesh.py +0 -0
  29. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/plotter/text.py +0 -0
  30. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/marsilea/utils.py +0 -0
  31. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/oncoprinter/__init__.py +0 -0
  32. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/oncoprinter/core.py +0 -0
  33. {marsilea-0.4.7 → marsilea-0.5.0rc1}/src/oncoprinter/preset.py +0 -0
@@ -1,10 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: marsilea
3
- Version: 0.4.7
4
- Dynamic: Summary
3
+ Version: 0.5.0rc1
4
+ Summary: Declarative creation of composable visualizations
5
5
  Project-URL: Home, https://github.com/Marsilea-viz/marsilea
6
+ Project-URL: Documentation, https://marsilea.readthedocs.io
6
7
  Author: Zhihang Zheng
7
- Author-email: Mr-Milk <yzheng@cemm.at>
8
+ Author-email: Yimin Zheng <yzheng@cemm.at>
8
9
  License: The MIT License (MIT)
9
10
 
10
11
  Copyright (c) 2024 Mr-Milk
@@ -30,6 +31,8 @@ License-File: LICENSE
30
31
  Classifier: Framework :: Matplotlib
31
32
  Classifier: License :: OSI Approved :: MIT License
32
33
  Classifier: Programming Language :: Python :: 3
34
+ Classifier: Topic :: Scientific/Engineering
35
+ Classifier: Topic :: Scientific/Engineering :: Visualization
33
36
  Requires-Python: >=3.8
34
37
  Requires-Dist: legendkit
35
38
  Requires-Dist: matplotlib>=3.6
@@ -38,20 +41,6 @@ Requires-Dist: pandas[parquet]
38
41
  Requires-Dist: platformdirs
39
42
  Requires-Dist: scipy
40
43
  Requires-Dist: seaborn
41
- Provides-Extra: dev
42
- Requires-Dist: icecream; extra == 'dev'
43
- Requires-Dist: mpl-fontkit; extra == 'dev'
44
- Requires-Dist: numpydoc; extra == 'dev'
45
- Requires-Dist: pre-commit; extra == 'dev'
46
- Requires-Dist: pydata-sphinx-theme; extra == 'dev'
47
- Requires-Dist: pytest; extra == 'dev'
48
- Requires-Dist: python-hmr; extra == 'dev'
49
- Requires-Dist: ruff; extra == 'dev'
50
- Requires-Dist: scikit-learn; extra == 'dev'
51
- Requires-Dist: sphinx; extra == 'dev'
52
- Requires-Dist: sphinx-copybutton; extra == 'dev'
53
- Requires-Dist: sphinx-design; extra == 'dev'
54
- Requires-Dist: sphinx-gallery; extra == 'dev'
55
44
  Description-Content-Type: text/markdown
56
45
 
57
46
  <p align="center">
@@ -66,6 +55,7 @@ Description-Content-Type: text/markdown
66
55
  ![pypi version](https://img.shields.io/pypi/v/marsilea?color=0098FF&logo=python&logoColor=white&style=flat-square)
67
56
  ![Conda Version](https://img.shields.io/conda/vn/conda-forge/marsilea?style=flat-square&logo=anaconda&logoColor=white&color=%2344A833)
68
57
  ![PyPI - License](https://img.shields.io/pypi/l/marsilea?color=FFD43B&style=flat-square)
58
+ [![DOI](https://img.shields.io/badge/DOI-10.1186%2Fs13059--024--03469--3-blue?color=0098FF&style=flat-square)](https://doi.org/10.1186/s13059-024-03469-3)
69
59
 
70
60
  # Marsilea: Declarative creation of composable visualization!
71
61
 
@@ -104,6 +94,16 @@ and then create a bar chart to show the expression of genes in different cell ty
104
94
  A visualization contains multiple plots is called a composable visualization.
105
95
  In Marsilea, we employ a declarative approach for user to create composable visualization incrementally.
106
96
 
97
+ ## Citation
98
+
99
+ If you use Marsilea in your research, please cite the following:
100
+
101
+ > Marsilea: an intuitive generalized paradigm for composable visualizations
102
+ >
103
+ > Yimin Zheng, Zhihang Zheng, André F. Rendeiro & Edwin Cheung
104
+ >
105
+ > _Genome Biology_ 2025 Jan 06. DOI: [10.1186/s13059-017-1382-0](https://doi.org/10.1186/s13059-024-03469-3)
106
+
107
107
  ## Examples
108
108
 
109
109
  <table>
@@ -10,6 +10,7 @@
10
10
  ![pypi version](https://img.shields.io/pypi/v/marsilea?color=0098FF&logo=python&logoColor=white&style=flat-square)
11
11
  ![Conda Version](https://img.shields.io/conda/vn/conda-forge/marsilea?style=flat-square&logo=anaconda&logoColor=white&color=%2344A833)
12
12
  ![PyPI - License](https://img.shields.io/pypi/l/marsilea?color=FFD43B&style=flat-square)
13
+ [![DOI](https://img.shields.io/badge/DOI-10.1186%2Fs13059--024--03469--3-blue?color=0098FF&style=flat-square)](https://doi.org/10.1186/s13059-024-03469-3)
13
14
 
14
15
  # Marsilea: Declarative creation of composable visualization!
15
16
 
@@ -48,6 +49,16 @@ and then create a bar chart to show the expression of genes in different cell ty
48
49
  A visualization contains multiple plots is called a composable visualization.
49
50
  In Marsilea, we employ a declarative approach for user to create composable visualization incrementally.
50
51
 
52
+ ## Citation
53
+
54
+ If you use Marsilea in your research, please cite the following:
55
+
56
+ > Marsilea: an intuitive generalized paradigm for composable visualizations
57
+ >
58
+ > Yimin Zheng, Zhihang Zheng, André F. Rendeiro & Edwin Cheung
59
+ >
60
+ > _Genome Biology_ 2025 Jan 06. DOI: [10.1186/s13059-017-1382-0](https://doi.org/10.1186/s13059-024-03469-3)
61
+
51
62
  ## Examples
52
63
 
53
64
  <table>
@@ -4,8 +4,9 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "marsilea"
7
+ description = "Declarative creation of composable visualizations"
7
8
  authors = [
8
- {name = "Mr-Milk", email = "yzheng@cemm.at"},
9
+ {name = "Yimin Zheng", email = "yzheng@cemm.at"},
9
10
  {name = "Zhihang Zheng"}
10
11
  ]
11
12
  license = {file = "LICENSE"}
@@ -14,10 +15,12 @@ classifiers = [
14
15
  "License :: OSI Approved :: MIT License",
15
16
  "Programming Language :: Python :: 3",
16
17
  "Framework :: Matplotlib",
18
+ "Topic :: Scientific/Engineering",
19
+ "Topic :: Scientific/Engineering :: Visualization",
17
20
  ]
18
- dynamic = ["version", "description"]
21
+ dynamic = ["version"]
19
22
  requires-python = ">=3.8"
20
- urls = {Home="https://github.com/Marsilea-viz/marsilea"}
23
+ urls = { Home="https://github.com/Marsilea-viz/marsilea", Documentation="https://marsilea.readthedocs.io"}
21
24
  dependencies = [
22
25
  "numpy",
23
26
  "pandas[parquet]",
@@ -28,23 +31,6 @@ dependencies = [
28
31
  "platformdirs"
29
32
  ]
30
33
 
31
- [project.optional-dependencies]
32
- dev = [
33
- "ruff",
34
- "icecream",
35
- "python-hmr",
36
- "pytest",
37
- "scikit-learn",
38
- "sphinx",
39
- "numpydoc",
40
- "sphinx_design",
41
- "pydata-sphinx-theme",
42
- "sphinx-copybutton",
43
- "sphinx_gallery",
44
- "mpl_fontkit",
45
- "pre-commit",
46
- ]
47
-
48
34
  [tool.hatch.version]
49
35
  path = "src/marsilea/__init__.py"
50
36
 
@@ -76,4 +62,30 @@ docstring-code-format = true
76
62
  [tool.ruff.lint.per-file-ignores]
77
63
  "__init__.py" = ["F401"]
78
64
  "docs/*" = ["E402", "E731"]
79
- "scripts/*" = ["E402", "E731"]
65
+ "scripts/*" = ["E402", "E731"]
66
+
67
+ [tool.taskipy.tasks]
68
+ hello = "echo Hello, World!"
69
+ test = "pytest tests"
70
+ doc-build = "sphinx-build -b html docs/source docs/build"
71
+ doc-clean-build = "python docs/clean_up.py && sphinx-build -b html docs/source docs/build"
72
+ doc-serve = "python -m http.server -d docs/build"
73
+ fmt = "ruff format docs/source wsidata tests"
74
+
75
+ [dependency-groups]
76
+ dev = [
77
+ "sphinx>=7.1.2",
78
+ "ruff",
79
+ "pytest",
80
+ "scikit-learn",
81
+ "sphinx",
82
+ "numpydoc",
83
+ "sphinx_design",
84
+ "pydata-sphinx-theme",
85
+ "sphinx-copybutton",
86
+ "sphinx_gallery",
87
+ "mpl_fontkit",
88
+ "pre-commit",
89
+ "taskipy",
90
+ "emoji>=2.14.1",
91
+ ]
@@ -1,6 +1,6 @@
1
1
  """Declarative creation of composable visualization"""
2
2
 
3
- __version__ = "0.4.7"
3
+ __version__ = "0.5.0rc1"
4
4
 
5
5
  import marsilea.plotter as plotter
6
6
  from ._deform import Deformation
@@ -169,7 +169,14 @@ class LegendMaker:
169
169
  for _, legs in legends.items():
170
170
  for leg in legs:
171
171
  try:
172
+ # Try to detach legend from figure
172
173
  leg.remove()
174
+ # For matplotlib >= 3.10.0
175
+ if hasattr(leg, "_parent_figure"):
176
+ setattr(leg, "_parent_figure", None)
177
+ # For matplotlib < 3.10.0
178
+ if hasattr(leg, "figure"):
179
+ setattr(leg, "figure", None)
173
180
  except Exception:
174
181
  pass
175
182
 
@@ -50,6 +50,7 @@ class Heatmap(ClusterBoard):
50
50
  height=None,
51
51
  cluster_data=None,
52
52
  init_main=True,
53
+ legend=True,
53
54
  **kwargs,
54
55
  ):
55
56
  if cluster_data is None:
@@ -80,7 +81,7 @@ class Heatmap(ClusterBoard):
80
81
  )
81
82
  name = get_plot_name(name, "main", mesh.__class__.__name__)
82
83
  mesh.set(name=name)
83
- self.add_layer(mesh)
84
+ self.add_layer(mesh, legend=legend)
84
85
 
85
86
 
86
87
  class CatHeatmap(ClusterBoard):
@@ -109,6 +110,7 @@ class CatHeatmap(ClusterBoard):
109
110
  name=None,
110
111
  width=None,
111
112
  height=None,
113
+ legend=True,
112
114
  cluster_data=None,
113
115
  linewidth=0,
114
116
  linecolor="white",
@@ -128,7 +130,7 @@ class CatHeatmap(ClusterBoard):
128
130
  super().__init__(cluster_data, width=width, height=height, name=name)
129
131
  name = get_plot_name(name, "main", mesh.__class__.__name__)
130
132
  mesh.set(name=name)
131
- self.add_layer(mesh)
133
+ self.add_layer(mesh, legend=legend)
132
134
 
133
135
 
134
136
  class SizedHeatmap(ClusterBoard):
@@ -156,6 +158,7 @@ class SizedHeatmap(ClusterBoard):
156
158
  name=None,
157
159
  width=None,
158
160
  height=None,
161
+ legend=True,
159
162
  **kwargs,
160
163
  ):
161
164
  if cluster_data is None:
@@ -166,4 +169,4 @@ class SizedHeatmap(ClusterBoard):
166
169
  super().__init__(cluster_data, width=width, height=height, name=name)
167
170
 
168
171
  mesh = SizedMesh(size=size, color=color, **kwargs)
169
- self.add_layer(mesh)
172
+ self.add_layer(mesh, legend=legend)
@@ -231,11 +231,9 @@ class Arc(StatsBase):
231
231
  ax.set_ylim(lim * 1.1, 0)
232
232
  ax.set_xlim(0, 1)
233
233
  if self.side == "top":
234
- if not ax.yaxis_inverted():
235
- ax.invert_yaxis()
234
+ ax.invert_yaxis()
236
235
  if self.side == "left":
237
- if not ax.xaxis_inverted():
238
- ax.invert_xaxis()
236
+ ax.invert_xaxis()
239
237
  ax.set_axis_off()
240
238
 
241
239
  def get_legends(self):
@@ -90,8 +90,7 @@ class Area(StatsBase):
90
90
  ax.plot(data, x, **line_options)
91
91
  ax.set_ylim(-0.5, len(data) - 0.5)
92
92
  if self.side == "left":
93
- if not ax.xaxis_inverted():
94
- ax.invert_xaxis()
93
+ ax.invert_xaxis()
95
94
  else:
96
95
  ax.fill_between(x, data, **fill_options)
97
96
  if self.add_outline:
@@ -270,8 +270,7 @@ class CenterBar(_BarBase):
270
270
  ax.xaxis.set_major_formatter(FuncFormatter(lambda x, p: f"{np.abs(x):g}"))
271
271
 
272
272
  if self.is_flank:
273
- if not ax.yaxis_inverted():
274
- ax.invert_yaxis()
273
+ ax.invert_yaxis()
275
274
 
276
275
  if self.show_value:
277
276
  left_label = _format_labels(left_bar, self.fmt)
@@ -171,12 +171,9 @@ class SeqLogo(StatsBase):
171
171
  ax.set_xlim(0, lim)
172
172
  ax.set_ylim(0, data.shape[1])
173
173
  if self.is_flank:
174
- if not ax.yaxis_inverted():
175
- ax.invert_yaxis()
174
+ ax.invert_yaxis()
176
175
  if self.side == "left":
177
- if not ax.xaxis_inverted():
178
- ax.invert_xaxis()
176
+ ax.invert_xaxis()
179
177
  if self.side == "bottom":
180
- if not ax.yaxis_inverted():
181
- ax.invert_yaxis()
178
+ ax.invert_yaxis()
182
179
  ax.set_axis_off()
@@ -125,8 +125,7 @@ class Range(StatsBase):
125
125
  else:
126
126
  ax.set_xlim(0, len(data))
127
127
  if self.side == "left":
128
- if not ax.xaxis_inverted():
129
- ax.invert_xaxis()
128
+ ax.invert_xaxis()
130
129
 
131
130
  def get_legends(self):
132
131
  return [
@@ -947,7 +947,7 @@ class Upset(WhiteBoard):
947
947
  def _extra_legends(self):
948
948
  handles = [Patch(**entry) for entry in self._legend_entries]
949
949
  highlight_legend = ListLegend(handles=handles, handlelength=2)
950
- highlight_legend.figure = None
950
+ # highlight_legend.set_figure(None)
951
951
  return {"highlight_subsets": [highlight_legend]}
952
952
 
953
953
  def render(self, figure=None, scale=1):
File without changes
File without changes
File without changes