marsilea 0.5.4__py3-none-any.whl → 0.5.6__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.
- marsilea/__init__.py +3 -1
- marsilea/_version.py +1 -0
- marsilea/base.py +24 -28
- marsilea/layout.py +2 -2
- marsilea/plotter/mesh.py +92 -18
- {marsilea-0.5.4.dist-info → marsilea-0.5.6.dist-info}/METADATA +1 -1
- {marsilea-0.5.4.dist-info → marsilea-0.5.6.dist-info}/RECORD +11 -10
- oncoprinter/core.py +1 -1
- oncoprinter/preset.py +3 -0
- {marsilea-0.5.4.dist-info → marsilea-0.5.6.dist-info}/WHEEL +0 -0
- {marsilea-0.5.4.dist-info → marsilea-0.5.6.dist-info}/licenses/LICENSE +0 -0
marsilea/__init__.py
CHANGED
marsilea/_version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "0.5.6"
|
marsilea/base.py
CHANGED
|
@@ -440,18 +440,16 @@ class WhiteBoard(LegendMaker):
|
|
|
440
440
|
self.add_plot("bottom", plot, name, size, pad, legend)
|
|
441
441
|
|
|
442
442
|
def _render_plan(self):
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
443
|
+
try:
|
|
444
|
+
for plan in self._col_plan + self._row_plan:
|
|
445
|
+
axes = self.layout.get_ax(plan.name)
|
|
446
|
+
plan.render(axes)
|
|
446
447
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
main_ax = self.get_main_ax()
|
|
453
|
-
for plan in self._get_layers_zorder():
|
|
454
|
-
plan.render(main_ax)
|
|
448
|
+
main_ax = self.get_main_ax()
|
|
449
|
+
for plan in self._get_layers_zorder():
|
|
450
|
+
plan.render(main_ax)
|
|
451
|
+
except Exception as e:
|
|
452
|
+
raise Exception(f"An error occur during rendering of {plan}") from e
|
|
455
453
|
|
|
456
454
|
def add_layer(self, plot: RenderPlan, zorder=None, name=None, legend=True):
|
|
457
455
|
"""Add a plotter to the main canvas
|
|
@@ -655,7 +653,8 @@ class WhiteBoard(LegendMaker):
|
|
|
655
653
|
def save(self, fname, **kwargs):
|
|
656
654
|
"""Save the figure to a file
|
|
657
655
|
|
|
658
|
-
|
|
656
|
+
Save the current opened figure to a file, if no figure is open,
|
|
657
|
+
a render will be performed first.
|
|
659
658
|
|
|
660
659
|
Parameters
|
|
661
660
|
----------
|
|
@@ -665,7 +664,8 @@ class WhiteBoard(LegendMaker):
|
|
|
665
664
|
Additional options for saving the figure, will be passed to :meth:`~matplotlib.pyplot.savefig`
|
|
666
665
|
|
|
667
666
|
"""
|
|
668
|
-
self.
|
|
667
|
+
if self.figure is None:
|
|
668
|
+
self.render()
|
|
669
669
|
save_options = dict(bbox_inches="tight")
|
|
670
670
|
save_options.update(kwargs)
|
|
671
671
|
self.figure.savefig(fname, **save_options)
|
|
@@ -1364,23 +1364,19 @@ class ClusterBoard(WhiteBoard):
|
|
|
1364
1364
|
|
|
1365
1365
|
def _render_plan(self):
|
|
1366
1366
|
deform = self.get_deform()
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
plan.
|
|
1370
|
-
|
|
1371
|
-
|
|
1367
|
+
try:
|
|
1368
|
+
for plan in self._col_plan + self._row_plan:
|
|
1369
|
+
if plan.allow_split:
|
|
1370
|
+
plan.set_deform(deform)
|
|
1371
|
+
axes = self.layout.get_ax(plan.name)
|
|
1372
|
+
plan.render(axes)
|
|
1372
1373
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
if plan.allow_split:
|
|
1374
|
+
main_ax = self.get_main_ax()
|
|
1375
|
+
for plan in self._get_layers_zorder():
|
|
1376
1376
|
plan.set_deform(deform)
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
main_ax = self.get_main_ax()
|
|
1381
|
-
for plan in self._get_layers_zorder():
|
|
1382
|
-
plan.set_deform(deform)
|
|
1383
|
-
plan.render(main_ax)
|
|
1377
|
+
plan.render(main_ax)
|
|
1378
|
+
except Exception as e:
|
|
1379
|
+
raise Exception(f"An error occur during rending of {plan}") from e
|
|
1384
1380
|
|
|
1385
1381
|
def get_deform(self):
|
|
1386
1382
|
"""Return the deformation object of the cluster data"""
|
marsilea/layout.py
CHANGED
|
@@ -461,8 +461,8 @@ class CrossLayout(_MarginMixin):
|
|
|
461
461
|
y = self.get_side_size("bottom")
|
|
462
462
|
if self.is_composite:
|
|
463
463
|
return x, y
|
|
464
|
-
x += self.margin.
|
|
465
|
-
y += self.margin.
|
|
464
|
+
x += self.margin.left
|
|
465
|
+
y += self.margin.bottom
|
|
466
466
|
return x, y
|
|
467
467
|
else:
|
|
468
468
|
return self.anchor
|
marsilea/plotter/mesh.py
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
__all__ = ["ColorMesh", "Colors", "SizedMesh", "MarkerMesh", "TextMesh", "PatchMesh"]
|
|
2
2
|
|
|
3
|
-
import numpy as np
|
|
4
|
-
import pandas as pd
|
|
5
3
|
import warnings
|
|
6
4
|
from itertools import cycle
|
|
7
|
-
from legendkit import ColorArt, CatLegend, SizeLegend
|
|
8
|
-
from matplotlib.cm import ScalarMappable
|
|
9
|
-
from matplotlib.colors import ListedColormap, TwoSlopeNorm, Normalize, is_color_like
|
|
10
5
|
from typing import Mapping
|
|
11
6
|
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pandas as pd
|
|
9
|
+
from legendkit import ColorArt, CatLegend, SizeLegend, ListLegend
|
|
10
|
+
from matplotlib.cm import ScalarMappable
|
|
11
|
+
from matplotlib.colors import (
|
|
12
|
+
ListedColormap,
|
|
13
|
+
TwoSlopeNorm,
|
|
14
|
+
Normalize,
|
|
15
|
+
is_color_like,
|
|
16
|
+
to_hex,
|
|
17
|
+
)
|
|
18
|
+
|
|
12
19
|
from ._utils import _format_label
|
|
13
20
|
from .base import RenderPlan
|
|
14
21
|
from ..layout import close_ticks
|
|
@@ -426,8 +433,9 @@ class SizedMesh(MeshBase):
|
|
|
426
433
|
The range of the size of elements
|
|
427
434
|
size_norm : :class:`matplotlib.colors.Normalize`
|
|
428
435
|
A Normalize instance to map size
|
|
429
|
-
edgecolor : color
|
|
430
|
-
The border color of each elements
|
|
436
|
+
edgecolor : color or array of colors
|
|
437
|
+
The border color of each elements, if you want to control every element,
|
|
438
|
+
please supply a 2d array with the same shape as input.
|
|
431
439
|
linewidth : float
|
|
432
440
|
The width of the border of each elements
|
|
433
441
|
frameon : bool
|
|
@@ -454,6 +462,10 @@ class SizedMesh(MeshBase):
|
|
|
454
462
|
Control the size legend, See :class:`legendkit.size_legend`
|
|
455
463
|
color_legend_kws : dict
|
|
456
464
|
Control the color legend, See :class:`legendkit.colorart`
|
|
465
|
+
edgecolor_legend_text : list of str
|
|
466
|
+
The texts for the edgecolor legend
|
|
467
|
+
edgecolor_legend_kws : dict
|
|
468
|
+
Control the edgecolor legend, See :class:`legendkit.legend`
|
|
457
469
|
kwargs : dict
|
|
458
470
|
Pass to :meth:`matplotlib.axes.Axes.scatter`
|
|
459
471
|
|
|
@@ -511,6 +523,8 @@ class SizedMesh(MeshBase):
|
|
|
511
523
|
legend=True,
|
|
512
524
|
size_legend_kws=None,
|
|
513
525
|
color_legend_kws=None,
|
|
526
|
+
edgecolor_legend_text=None,
|
|
527
|
+
edgecolor_legend_kws=None,
|
|
514
528
|
**kwargs,
|
|
515
529
|
):
|
|
516
530
|
# normalize size
|
|
@@ -528,6 +542,11 @@ class SizedMesh(MeshBase):
|
|
|
528
542
|
self.legend = legend
|
|
529
543
|
self.color_legend_kws = {} if color_legend_kws is None else color_legend_kws
|
|
530
544
|
self.size_legend_kws = {} if size_legend_kws is None else size_legend_kws
|
|
545
|
+
self.edgecolor_legend_text = edgecolor_legend_text
|
|
546
|
+
self.edgecolor_legend_kws = (
|
|
547
|
+
{} if edgecolor_legend_kws is None else edgecolor_legend_kws
|
|
548
|
+
)
|
|
549
|
+
|
|
531
550
|
self._has_colormesh = False
|
|
532
551
|
# process color
|
|
533
552
|
# By default, the circles colors are uniform
|
|
@@ -557,7 +576,25 @@ class SizedMesh(MeshBase):
|
|
|
557
576
|
self._has_colormesh = True
|
|
558
577
|
self.alpha = alpha
|
|
559
578
|
self.frameon = frameon
|
|
560
|
-
|
|
579
|
+
|
|
580
|
+
if edgecolor is not None:
|
|
581
|
+
if is_color_like(edgecolor):
|
|
582
|
+
self.edgecolor = np.repeat(edgecolor, size.size).reshape(size.shape)
|
|
583
|
+
self._single_edgecolor = True
|
|
584
|
+
else:
|
|
585
|
+
edgecolor = np.asarray(edgecolor)
|
|
586
|
+
if edgecolor.shape != self.size_matrix.shape:
|
|
587
|
+
raise ValueError(
|
|
588
|
+
"If use multiple edgecolors, "
|
|
589
|
+
"the shape must be the same as input size"
|
|
590
|
+
)
|
|
591
|
+
# Covert to hex
|
|
592
|
+
edgecolor = [[to_hex(c) for c in row] for row in edgecolor]
|
|
593
|
+
self.edgecolor = np.asarray(edgecolor)
|
|
594
|
+
self._single_edgecolor = False
|
|
595
|
+
else:
|
|
596
|
+
self.edgecolor = np.full_like(size, "#00000000", dtype=object)
|
|
597
|
+
self._single_edgecolor = True
|
|
561
598
|
self.linewidth = linewidth
|
|
562
599
|
self.set_label(label, label_loc, label_props)
|
|
563
600
|
self.grid = grid
|
|
@@ -566,7 +603,12 @@ class SizedMesh(MeshBase):
|
|
|
566
603
|
self.kwargs = kwargs
|
|
567
604
|
|
|
568
605
|
self._collections = None
|
|
569
|
-
self.
|
|
606
|
+
self._transparent_marker = "none" in self.color2d
|
|
607
|
+
render_data = [self.size_matrix, self.color2d]
|
|
608
|
+
if self.edgecolor is not None:
|
|
609
|
+
render_data.append(self.edgecolor)
|
|
610
|
+
|
|
611
|
+
self.set_data(*render_data)
|
|
570
612
|
|
|
571
613
|
def update_main_canvas_size(self):
|
|
572
614
|
return get_canvas_size_by_data(self.orig_size.shape)
|
|
@@ -574,11 +616,20 @@ class SizedMesh(MeshBase):
|
|
|
574
616
|
def get_legends(self):
|
|
575
617
|
if not self.legend:
|
|
576
618
|
return None
|
|
619
|
+
|
|
620
|
+
legends = []
|
|
621
|
+
|
|
577
622
|
if self.color is not None:
|
|
578
623
|
size_color = self.color
|
|
579
624
|
else:
|
|
580
625
|
size_color = "black"
|
|
581
|
-
|
|
626
|
+
edgecolor = None
|
|
627
|
+
if self.edgecolor is not None:
|
|
628
|
+
if self._single_edgecolor:
|
|
629
|
+
edgecolor = self.edgecolor.flatten()[0]
|
|
630
|
+
if self._transparent_marker & (edgecolor is None):
|
|
631
|
+
edgecolor = "black"
|
|
632
|
+
handler_kw = dict(edgecolor=edgecolor, linewidth=self.linewidth)
|
|
582
633
|
options = dict(
|
|
583
634
|
colors=size_color,
|
|
584
635
|
handle=self.marker,
|
|
@@ -588,8 +639,27 @@ class SizedMesh(MeshBase):
|
|
|
588
639
|
)
|
|
589
640
|
options.update(self.size_legend_kws)
|
|
590
641
|
size_legend = SizeLegend(self.size_matrix, array=self.orig_size, **options)
|
|
591
|
-
|
|
592
|
-
|
|
642
|
+
legends.append(size_legend)
|
|
643
|
+
|
|
644
|
+
# Construct edgecolor legend
|
|
645
|
+
if self.edgecolor is not None:
|
|
646
|
+
if self.edgecolor_legend_text is not None:
|
|
647
|
+
unique_ecs = np.unique(self.edgecolor)
|
|
648
|
+
if len(self.edgecolor_legend_text) == len(unique_ecs):
|
|
649
|
+
legend_items = [
|
|
650
|
+
("circle", text, dict(ec=ec, fc="none", lw=self.linewidth))
|
|
651
|
+
for text, ec in zip(self.edgecolor_legend_text, unique_ecs)
|
|
652
|
+
]
|
|
653
|
+
ec_legend = ListLegend(
|
|
654
|
+
legend_items=legend_items, **self.color_legend_kws
|
|
655
|
+
)
|
|
656
|
+
legends.append(ec_legend)
|
|
657
|
+
else:
|
|
658
|
+
raise ValueError(
|
|
659
|
+
"If edgecolor legend text is provided, the number of unique edgecolors "
|
|
660
|
+
"must match the number of texts"
|
|
661
|
+
)
|
|
662
|
+
if self._has_colormesh & (self._transparent_marker):
|
|
593
663
|
if self.palette is not None:
|
|
594
664
|
labels, colors = [], []
|
|
595
665
|
for label, c in self.palette.items():
|
|
@@ -606,16 +676,20 @@ class SizedMesh(MeshBase):
|
|
|
606
676
|
else:
|
|
607
677
|
ScalarMappable(norm=self.norm, cmap=self.cmap)
|
|
608
678
|
color_legend = ColorArt(self._collections, **self.color_legend_kws)
|
|
609
|
-
|
|
679
|
+
legends.append(color_legend)
|
|
680
|
+
|
|
681
|
+
if len(legends) == 1:
|
|
682
|
+
return legends[0]
|
|
610
683
|
else:
|
|
611
|
-
return
|
|
684
|
+
return legends
|
|
612
685
|
|
|
613
686
|
def render_ax(self, spec):
|
|
614
687
|
ax = spec.ax
|
|
615
|
-
size, color = spec.data
|
|
688
|
+
size, color, edgecolors = spec.data
|
|
616
689
|
if self.is_flank:
|
|
617
690
|
size = size.T
|
|
618
691
|
color = color.T
|
|
692
|
+
edgecolors = edgecolors.T
|
|
619
693
|
Y, X = size.shape
|
|
620
694
|
xticks = np.arange(X) + 0.5
|
|
621
695
|
yticks = np.arange(Y) + 0.5
|
|
@@ -633,14 +707,14 @@ class SizedMesh(MeshBase):
|
|
|
633
707
|
|
|
634
708
|
options = dict(
|
|
635
709
|
s=size,
|
|
636
|
-
|
|
710
|
+
edgecolors=edgecolors.flatten(),
|
|
637
711
|
linewidths=self.linewidth,
|
|
638
712
|
marker=self.marker,
|
|
639
713
|
)
|
|
640
714
|
if self.color is not None:
|
|
641
|
-
options["c"] = color
|
|
715
|
+
options["c"] = color.flatten()
|
|
642
716
|
else:
|
|
643
|
-
options.update(dict(c=color, norm=self.norm, cmap=self.cmap))
|
|
717
|
+
options.update(dict(c=color.flatten(), norm=self.norm, cmap=self.cmap))
|
|
644
718
|
self._collections = ax.scatter(xv, yv, **options, **self.kwargs)
|
|
645
719
|
|
|
646
720
|
close_ticks(ax)
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
marsilea/__init__.py,sha256=
|
|
1
|
+
marsilea/__init__.py,sha256=mMtII0QzSVGrr1vJXTglr6wBd2AHElrDnDp1iGQbOxo,626
|
|
2
2
|
marsilea/_api.py,sha256=tymWZHfjhx8-0NNd9762znfdIu36NrARRweEIr5L1mA,283
|
|
3
3
|
marsilea/_deform.py,sha256=QRz4OGXMsQzbiIkC3ASzZayMPhHhoFsEK38oBzSeQG8,14440
|
|
4
|
-
marsilea/
|
|
4
|
+
marsilea/_version.py,sha256=FtfC8ptaFH0Unc72bPRynMH_N62bxa4tnazGgIcgnTY,18
|
|
5
|
+
marsilea/base.py,sha256=GBgSirueH65nhfkunCVYhV7ePX4i01jog5gzkBBOsi0,46951
|
|
5
6
|
marsilea/dataset.py,sha256=Qh8k1DhTiwP_Me709CkpNwRaYLDzlenRTIk0U6D58_g,4631
|
|
6
7
|
marsilea/dendrogram.py,sha256=Ung43zseybZKzTEvH5P_ge3WGfsr7i7qsX7YEVDlC74,15590
|
|
7
8
|
marsilea/exceptions.py,sha256=wN5ElUZxuaJKSnnwWdkNx6P-Oc16dzSuaRPbRKWIBEM,1046
|
|
8
9
|
marsilea/heatmap.py,sha256=8Wo1NxFTBp1a7NOISmer0yQYWWgf51Xsvjav1h1vTYk,4316
|
|
9
10
|
marsilea/layers.py,sha256=w_yvghwYAO112mVvp1krjUjEIQYq_1nz2uCsTUJdB-Y,12909
|
|
10
|
-
marsilea/layout.py,sha256=
|
|
11
|
+
marsilea/layout.py,sha256=b6aynXl2senRYjaYnNikjIzK84RkXaBvAyt86VRWw-g,39741
|
|
11
12
|
marsilea/upset.py,sha256=9m4Los-yVvVZOEHg6X-yfOdLA9eUBQdK1A_BkOaLIMA,30602
|
|
12
13
|
marsilea/utils.py,sha256=y_KYs4ToiuKEsiBdmcIVtmxMXFpD4wKiJ0k7iBa11z8,2854
|
|
13
14
|
marsilea/plotter/__init__.py,sha256=la30o20zYiHWN2RzElhS8MMCbGKbDDEe0WHXakq9OBQ,806
|
|
@@ -19,13 +20,13 @@ marsilea/plotter/bar.py,sha256=RWDsNbyCUKbybpsBOgbl43lVZc_ynZmTOevE-CtJ5KE,12354
|
|
|
19
20
|
marsilea/plotter/base.py,sha256=b_NmrW_oNPc-HwQsjx1NsC2lknYK6qSaDp_7SxeoUEM,18938
|
|
20
21
|
marsilea/plotter/bio.py,sha256=34tucmxs4LM3TFZoGsrjnXTolyrzYaHVEiRe4dzDH68,5040
|
|
21
22
|
marsilea/plotter/images.py,sha256=gb0xIQhUch3rNAt3FfvuUoamSGEynoBBBky2eE754ec,9560
|
|
22
|
-
marsilea/plotter/mesh.py,sha256=
|
|
23
|
+
marsilea/plotter/mesh.py,sha256=ARDPWrQLbdIS22B7Ct_aYPXY7IxwVKcICdBBhg8UplE,27482
|
|
23
24
|
marsilea/plotter/range.py,sha256=sXWKrvpq7nU7giiHPjayM7h9Q7gblhjXxHm8ioB3cm4,3770
|
|
24
25
|
marsilea/plotter/text.py,sha256=6S4mnAxLJLMkduKiyor03lPd86oTOJ5TojVREA9oU6s,37466
|
|
25
26
|
oncoprinter/__init__.py,sha256=efshcAD1h9s-NVJj4HLU9-hXc_LtTeIrNYqLHl-sm_g,106
|
|
26
|
-
oncoprinter/core.py,sha256=
|
|
27
|
-
oncoprinter/preset.py,sha256=
|
|
28
|
-
marsilea-0.5.
|
|
29
|
-
marsilea-0.5.
|
|
30
|
-
marsilea-0.5.
|
|
31
|
-
marsilea-0.5.
|
|
27
|
+
oncoprinter/core.py,sha256=XBIwTsAvcA-mJSwHU0xpaTBCxBNh7yusmzblRATmekY,11866
|
|
28
|
+
oncoprinter/preset.py,sha256=lo6Llz31KVFt3QOFgFc0BunloZV1FxcFVpH8kOfarNw,8363
|
|
29
|
+
marsilea-0.5.6.dist-info/METADATA,sha256=Ve7qLr7YzOz8bKG10ZIgJHYxPSiGyOXfdhhQrk4oDTE,7265
|
|
30
|
+
marsilea-0.5.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
31
|
+
marsilea-0.5.6.dist-info/licenses/LICENSE,sha256=RhHHDuP61qzKmfHtOQUVLZfCgMkKx9PXzxzkLtmAjHo,1078
|
|
32
|
+
marsilea-0.5.6.dist-info/RECORD,,
|
oncoprinter/core.py
CHANGED
|
@@ -168,7 +168,7 @@ class GenomicData:
|
|
|
168
168
|
cs = {}
|
|
169
169
|
for track, df in gb:
|
|
170
170
|
cs[track] = Counter(df["event"])
|
|
171
|
-
return pd.DataFrame(cs).fillna(0.0)
|
|
171
|
+
return pd.DataFrame(cs).fillna(0.0).loc[:, self.tracks]
|
|
172
172
|
|
|
173
173
|
def get_sample_mutation_types(self):
|
|
174
174
|
gb = self.data.groupby("sample", sort=False, observed=True)
|
oncoprinter/preset.py
CHANGED
|
@@ -125,6 +125,9 @@ class MatchRule:
|
|
|
125
125
|
|
|
126
126
|
MATCH_POOL = {
|
|
127
127
|
Alteration.AMP: MatchRule(startswith="amp"),
|
|
128
|
+
Alteration.BACKGROUND: MatchRule(
|
|
129
|
+
contains=["background", "no", "none", "na", "nan", "bg"], flexible=True
|
|
130
|
+
),
|
|
128
131
|
Alteration.GAIN: MatchRule(startswith="gain"),
|
|
129
132
|
Alteration.HOMDEL: MatchRule(
|
|
130
133
|
startswith="homdel", contains=["deep", "deletion"], flexible=True
|
|
File without changes
|
|
File without changes
|