plotnine 0.14.5__py3-none-any.whl → 0.15.0a2__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.
- plotnine/__init__.py +31 -37
- plotnine/_mpl/gridspec.py +265 -0
- plotnine/_mpl/layout_manager/__init__.py +6 -0
- plotnine/_mpl/layout_manager/_engine.py +87 -0
- plotnine/_mpl/layout_manager/_layout_items.py +957 -0
- plotnine/_mpl/layout_manager/_layout_tree.py +905 -0
- plotnine/_mpl/layout_manager/_spaces.py +1154 -0
- plotnine/_mpl/patches.py +70 -34
- plotnine/_mpl/text.py +159 -37
- plotnine/_mpl/utils.py +78 -10
- plotnine/_utils/__init__.py +35 -9
- plotnine/_utils/dev.py +45 -27
- plotnine/_utils/yippie.py +115 -0
- plotnine/animation.py +1 -1
- plotnine/coords/coord.py +3 -3
- plotnine/coords/coord_trans.py +1 -1
- plotnine/data/__init__.py +43 -8
- plotnine/data/anscombe-quartet.csv +45 -0
- plotnine/doctools.py +2 -2
- plotnine/facets/facet.py +34 -43
- plotnine/facets/facet_grid.py +14 -6
- plotnine/facets/facet_wrap.py +3 -5
- plotnine/facets/strips.py +20 -33
- plotnine/geoms/annotate.py +3 -3
- plotnine/geoms/annotation_logticks.py +2 -0
- plotnine/geoms/annotation_stripes.py +2 -0
- plotnine/geoms/geom.py +3 -3
- plotnine/geoms/geom_bar.py +10 -2
- plotnine/geoms/geom_col.py +6 -0
- plotnine/geoms/geom_crossbar.py +2 -3
- plotnine/geoms/geom_path.py +2 -2
- plotnine/geoms/geom_violin.py +24 -7
- plotnine/ggplot.py +95 -66
- plotnine/guides/guide.py +19 -20
- plotnine/guides/guide_colorbar.py +6 -6
- plotnine/guides/guide_legend.py +15 -16
- plotnine/guides/guides.py +8 -8
- plotnine/helpers.py +49 -0
- plotnine/iapi.py +33 -7
- plotnine/labels.py +8 -3
- plotnine/layer.py +4 -4
- plotnine/mapping/_env.py +2 -2
- plotnine/mapping/_eval_environment.py +85 -0
- plotnine/mapping/aes.py +14 -30
- plotnine/mapping/evaluation.py +7 -65
- plotnine/options.py +14 -7
- plotnine/plot_composition/__init__.py +10 -0
- plotnine/plot_composition/_compose.py +462 -0
- plotnine/plot_composition/_plotspec.py +50 -0
- plotnine/plot_composition/_spacer.py +32 -0
- plotnine/positions/position_dodge.py +1 -1
- plotnine/positions/position_dodge2.py +1 -1
- plotnine/positions/position_stack.py +1 -2
- plotnine/qplot.py +1 -2
- plotnine/scales/__init__.py +0 -6
- plotnine/scales/limits.py +7 -7
- plotnine/scales/scale.py +4 -4
- plotnine/scales/scale_continuous.py +2 -1
- plotnine/scales/scale_identity.py +10 -2
- plotnine/scales/scale_manual.py +6 -2
- plotnine/stats/binning.py +5 -2
- plotnine/stats/smoothers.py +3 -5
- plotnine/stats/stat.py +3 -3
- plotnine/stats/stat_bindot.py +1 -3
- plotnine/stats/stat_density.py +2 -2
- plotnine/stats/stat_qq_line.py +1 -1
- plotnine/stats/stat_sina.py +34 -1
- plotnine/themes/elements/__init__.py +3 -0
- plotnine/themes/elements/element_text.py +35 -24
- plotnine/themes/elements/margin.py +137 -61
- plotnine/themes/targets.py +3 -1
- plotnine/themes/theme.py +21 -7
- plotnine/themes/theme_538.py +0 -1
- plotnine/themes/theme_bw.py +0 -1
- plotnine/themes/theme_dark.py +0 -1
- plotnine/themes/theme_gray.py +32 -34
- plotnine/themes/theme_light.py +1 -1
- plotnine/themes/theme_matplotlib.py +28 -31
- plotnine/themes/theme_seaborn.py +36 -36
- plotnine/themes/theme_void.py +25 -27
- plotnine/themes/theme_xkcd.py +0 -1
- plotnine/themes/themeable.py +369 -169
- plotnine/typing.py +3 -3
- plotnine/watermark.py +3 -3
- {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info}/METADATA +8 -5
- {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info}/RECORD +89 -78
- {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info}/WHEEL +1 -1
- plotnine/_mpl/_plot_side_space.py +0 -888
- plotnine/_mpl/_plotnine_tight_layout.py +0 -293
- plotnine/_mpl/layout_engine.py +0 -110
- {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info/licenses}/LICENSE +0 -0
- {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info}/top_level.txt +0 -0
plotnine/themes/themeable.py
CHANGED
|
@@ -377,6 +377,36 @@ class Themeables(dict[str, themeable]):
|
|
|
377
377
|
|
|
378
378
|
return default
|
|
379
379
|
|
|
380
|
+
def get_ha(self, name: str) -> float:
|
|
381
|
+
"""
|
|
382
|
+
Get the horizontal alignement of themeable as a float
|
|
383
|
+
|
|
384
|
+
The themeable should be and element_text
|
|
385
|
+
"""
|
|
386
|
+
lookup = {"left": 0.0, "center": 0.5, "right": 1.0}
|
|
387
|
+
ha: str | float = self.getp((name, "ha"), "center")
|
|
388
|
+
if isinstance(ha, str):
|
|
389
|
+
ha = lookup[ha]
|
|
390
|
+
return ha
|
|
391
|
+
|
|
392
|
+
def get_va(self, name) -> float:
|
|
393
|
+
"""
|
|
394
|
+
Get the vertical alignement of themeable as a float
|
|
395
|
+
|
|
396
|
+
The themeable should be and element_text
|
|
397
|
+
"""
|
|
398
|
+
lookup = {
|
|
399
|
+
"bottom": 0.0,
|
|
400
|
+
"center": 0.5,
|
|
401
|
+
"baseline": 0.5,
|
|
402
|
+
"center_baseline": 0.5,
|
|
403
|
+
"top": 1.0,
|
|
404
|
+
}
|
|
405
|
+
va: str | float = self.getp((name, "va"), "center")
|
|
406
|
+
if isinstance(va, str):
|
|
407
|
+
va = lookup[va]
|
|
408
|
+
return va
|
|
409
|
+
|
|
380
410
|
def property(self, name: str, key: str = "value") -> Any:
|
|
381
411
|
"""
|
|
382
412
|
Get the value a specific themeable(s) property
|
|
@@ -719,6 +749,100 @@ class plot_caption(themeable):
|
|
|
719
749
|
text.set_visible(False)
|
|
720
750
|
|
|
721
751
|
|
|
752
|
+
class plot_tag(themeable):
|
|
753
|
+
"""
|
|
754
|
+
Plot tag
|
|
755
|
+
|
|
756
|
+
Parameters
|
|
757
|
+
----------
|
|
758
|
+
theme_element : element_text
|
|
759
|
+
|
|
760
|
+
Notes
|
|
761
|
+
-----
|
|
762
|
+
The `ha` & `va` of element_text have no effect in some cases. e.g.
|
|
763
|
+
if [](:class:`~plotnine.themes.themeable.plot_tag_position`) is "margin"
|
|
764
|
+
and the tag is at the top it cannot be vertically aligned.
|
|
765
|
+
|
|
766
|
+
Also `ha` & `va` can be floats if it makes sense to justify the tag
|
|
767
|
+
over a span. e.g. along the panel or plot, or when aligning with
|
|
768
|
+
other tags in a composition.
|
|
769
|
+
"""
|
|
770
|
+
|
|
771
|
+
_omit = ["margin"]
|
|
772
|
+
|
|
773
|
+
def apply_figure(self, figure: Figure, targets: ThemeTargets):
|
|
774
|
+
super().apply_figure(figure, targets)
|
|
775
|
+
props = self.properties
|
|
776
|
+
|
|
777
|
+
if "va" in props and not isinstance(props["va"], str):
|
|
778
|
+
del props["va"]
|
|
779
|
+
|
|
780
|
+
if "ha" in props and not isinstance(props["ha"], str):
|
|
781
|
+
del props["ha"]
|
|
782
|
+
|
|
783
|
+
if text := targets.plot_tag:
|
|
784
|
+
text.set(**props)
|
|
785
|
+
|
|
786
|
+
def blank_figure(self, figure: Figure, targets: ThemeTargets):
|
|
787
|
+
super().blank_figure(figure, targets)
|
|
788
|
+
if text := targets.plot_tag:
|
|
789
|
+
text.set_visible(False)
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
class plot_title_position(themeable):
|
|
793
|
+
"""
|
|
794
|
+
How to align the plot title and plot subtitle
|
|
795
|
+
|
|
796
|
+
Parameters
|
|
797
|
+
----------
|
|
798
|
+
theme_element : Literal["panel", "plot"], default = "panel"
|
|
799
|
+
If "panel", the title / subtitle are aligned with respect
|
|
800
|
+
to the panels. If "plot", they are aligned with the plot,
|
|
801
|
+
excluding the margin space
|
|
802
|
+
"""
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
class plot_caption_position(themeable):
|
|
806
|
+
"""
|
|
807
|
+
How to align the plot caption
|
|
808
|
+
|
|
809
|
+
Parameters
|
|
810
|
+
----------
|
|
811
|
+
theme_element : Literal["panel", "plot"], default = "panel"
|
|
812
|
+
If "panel", the caption is aligned with respect to the
|
|
813
|
+
panels. If "plot", it is aligned with the plot, excluding
|
|
814
|
+
the margin space.
|
|
815
|
+
"""
|
|
816
|
+
|
|
817
|
+
|
|
818
|
+
class plot_tag_location(themeable):
|
|
819
|
+
"""
|
|
820
|
+
The area where the tag will be positioned
|
|
821
|
+
|
|
822
|
+
Parameters
|
|
823
|
+
----------
|
|
824
|
+
theme_element : Literal["margin", "plot", "panel"], default = "margin"
|
|
825
|
+
If "margin", it is placed within the plot_margin.
|
|
826
|
+
If "plot", it is placed in the figure, ignoring any margins.
|
|
827
|
+
If "panel", it is placed within the panel area.
|
|
828
|
+
"""
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
class plot_tag_position(themeable):
|
|
832
|
+
"""
|
|
833
|
+
Position of the tag
|
|
834
|
+
|
|
835
|
+
Parameters
|
|
836
|
+
----------
|
|
837
|
+
theme_element : Literal["topleft", "top", "topright", "left" \
|
|
838
|
+
"right", "bottomleft", "bottom", "bottomleft"] \
|
|
839
|
+
| tuple[float, float], default = "topleft"
|
|
840
|
+
If the value is a string, the tag will be managed by the layout
|
|
841
|
+
manager. If it is a tuple of (x, y) coordinates, they should be
|
|
842
|
+
in figure space and the tag will be ignored by the layout manager.
|
|
843
|
+
"""
|
|
844
|
+
|
|
845
|
+
|
|
722
846
|
class strip_text_x(MixinSequenceOfValues):
|
|
723
847
|
"""
|
|
724
848
|
Facet labels along the horizontal axis
|
|
@@ -728,7 +852,7 @@ class strip_text_x(MixinSequenceOfValues):
|
|
|
728
852
|
theme_element : element_text
|
|
729
853
|
"""
|
|
730
854
|
|
|
731
|
-
_omit = ["margin"]
|
|
855
|
+
_omit = ["margin", "ha", "va"]
|
|
732
856
|
|
|
733
857
|
def apply_figure(self, figure: Figure, targets: ThemeTargets):
|
|
734
858
|
super().apply_figure(figure, targets)
|
|
@@ -751,7 +875,7 @@ class strip_text_y(MixinSequenceOfValues):
|
|
|
751
875
|
theme_element : element_text
|
|
752
876
|
"""
|
|
753
877
|
|
|
754
|
-
_omit = ["margin"]
|
|
878
|
+
_omit = ["margin", "ha", "va"]
|
|
755
879
|
|
|
756
880
|
def apply_figure(self, figure: Figure, targets: ThemeTargets):
|
|
757
881
|
super().apply_figure(figure, targets)
|
|
@@ -775,7 +899,9 @@ class strip_text(strip_text_x, strip_text_y):
|
|
|
775
899
|
"""
|
|
776
900
|
|
|
777
901
|
|
|
778
|
-
class title(
|
|
902
|
+
class title(
|
|
903
|
+
axis_title, legend_title, plot_title, plot_subtitle, plot_caption, plot_tag
|
|
904
|
+
):
|
|
779
905
|
"""
|
|
780
906
|
All titles on the plot
|
|
781
907
|
|
|
@@ -792,19 +918,45 @@ class axis_text_x(MixinSequenceOfValues):
|
|
|
792
918
|
Parameters
|
|
793
919
|
----------
|
|
794
920
|
theme_element : element_text
|
|
921
|
+
|
|
922
|
+
Notes
|
|
923
|
+
-----
|
|
924
|
+
Use the `margin` to control the gap between the ticks and the
|
|
925
|
+
text. e.g.
|
|
926
|
+
|
|
927
|
+
```python
|
|
928
|
+
theme(axis_text_x=element_text(margin={"t": 5, "units": "pt"}))
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
creates a margin of 5 points.
|
|
795
932
|
"""
|
|
796
933
|
|
|
797
|
-
_omit = ["margin"]
|
|
934
|
+
_omit = ["margin", "va"]
|
|
798
935
|
|
|
799
936
|
def apply_ax(self, ax: Axes):
|
|
800
937
|
super().apply_ax(ax)
|
|
801
|
-
|
|
938
|
+
|
|
939
|
+
# TODO: Remove this code when the minimum matplotlib >= 3.10.0,
|
|
940
|
+
# and use the commented one below it
|
|
941
|
+
import matplotlib as mpl
|
|
942
|
+
from packaging import version
|
|
943
|
+
|
|
944
|
+
vinstalled = version.parse(mpl.__version__)
|
|
945
|
+
v310 = version.parse("3.10.0")
|
|
946
|
+
name = "labelbottom" if vinstalled >= v310 else "labelleft"
|
|
947
|
+
if not ax.xaxis.get_tick_params()[name]:
|
|
948
|
+
return
|
|
949
|
+
|
|
950
|
+
# if not ax.xaxis.get_tick_params()["labelbottom"]:
|
|
951
|
+
# return
|
|
952
|
+
|
|
953
|
+
labels = [t.label1 for t in ax.xaxis.get_major_ticks()]
|
|
954
|
+
self.set(labels)
|
|
802
955
|
|
|
803
956
|
def blank_ax(self, ax: Axes):
|
|
804
957
|
super().blank_ax(ax)
|
|
805
|
-
ax.xaxis.
|
|
806
|
-
|
|
807
|
-
)
|
|
958
|
+
for t in ax.xaxis.get_major_ticks():
|
|
959
|
+
t.label1.set_visible(False)
|
|
808
960
|
|
|
809
961
|
|
|
810
962
|
class axis_text_y(MixinSequenceOfValues):
|
|
@@ -814,19 +966,34 @@ class axis_text_y(MixinSequenceOfValues):
|
|
|
814
966
|
Parameters
|
|
815
967
|
----------
|
|
816
968
|
theme_element : element_text
|
|
969
|
+
|
|
970
|
+
Notes
|
|
971
|
+
-----
|
|
972
|
+
Use the `margin` to control the gap between the ticks and the
|
|
973
|
+
text. e.g.
|
|
974
|
+
|
|
975
|
+
```python
|
|
976
|
+
theme(axis_text_y=element_text(margin={"r": 5, "units": "pt"}))
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
creates a margin of 5 points.
|
|
817
980
|
"""
|
|
818
981
|
|
|
819
|
-
_omit = ["margin"]
|
|
982
|
+
_omit = ["margin", "ha"]
|
|
820
983
|
|
|
821
984
|
def apply_ax(self, ax: Axes):
|
|
822
985
|
super().apply_ax(ax)
|
|
823
|
-
|
|
986
|
+
|
|
987
|
+
if not ax.yaxis.get_tick_params()["labelleft"]:
|
|
988
|
+
return
|
|
989
|
+
|
|
990
|
+
labels = [t.label1 for t in ax.yaxis.get_major_ticks()]
|
|
991
|
+
self.set(labels)
|
|
824
992
|
|
|
825
993
|
def blank_ax(self, ax: Axes):
|
|
826
994
|
super().blank_ax(ax)
|
|
827
|
-
ax.yaxis.
|
|
828
|
-
|
|
829
|
-
)
|
|
995
|
+
for t in ax.yaxis.get_major_ticks():
|
|
996
|
+
t.label1.set_visible(False)
|
|
830
997
|
|
|
831
998
|
|
|
832
999
|
class axis_text(axis_text_x, axis_text_y):
|
|
@@ -836,6 +1003,17 @@ class axis_text(axis_text_x, axis_text_y):
|
|
|
836
1003
|
Parameters
|
|
837
1004
|
----------
|
|
838
1005
|
theme_element : element_text
|
|
1006
|
+
|
|
1007
|
+
Notes
|
|
1008
|
+
-----
|
|
1009
|
+
Use the `margin` to control the gap between the ticks and the
|
|
1010
|
+
text. e.g.
|
|
1011
|
+
|
|
1012
|
+
```python
|
|
1013
|
+
theme(axis_text=element_text(margin={"t": 5, "r": 5, "units": "pt"}))
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
creates a margin of 5 points.
|
|
839
1017
|
"""
|
|
840
1018
|
|
|
841
1019
|
|
|
@@ -962,7 +1140,7 @@ class axis_ticks_minor_x(MixinSequenceOfValues):
|
|
|
962
1140
|
# to invisible. Theming should not change those artists to visible,
|
|
963
1141
|
# so we return early.
|
|
964
1142
|
params = ax.xaxis.get_tick_params(which="minor")
|
|
965
|
-
if not params.get("
|
|
1143
|
+
if not params.get("bottom", False):
|
|
966
1144
|
return
|
|
967
1145
|
|
|
968
1146
|
# We have to use both
|
|
@@ -1330,8 +1508,13 @@ class legend_key(MixinSequenceOfValues):
|
|
|
1330
1508
|
def apply_figure(self, figure: Figure, targets: ThemeTargets):
|
|
1331
1509
|
super().apply_figure(figure, targets)
|
|
1332
1510
|
properties = self.properties
|
|
1511
|
+
edgecolor = properties.get("edgecolor", None)
|
|
1512
|
+
|
|
1513
|
+
if isinstance(self, rect) and edgecolor:
|
|
1514
|
+
del properties["edgecolor"]
|
|
1515
|
+
|
|
1333
1516
|
# Prevent invisible strokes from having any effect
|
|
1334
|
-
if
|
|
1517
|
+
if edgecolor in ("none", "None"):
|
|
1335
1518
|
properties["linewidth"] = 0
|
|
1336
1519
|
|
|
1337
1520
|
rects = [da.patch for da in targets.legend_key]
|
|
@@ -1415,7 +1598,7 @@ class legend_box_background(themeable):
|
|
|
1415
1598
|
"""
|
|
1416
1599
|
|
|
1417
1600
|
|
|
1418
|
-
class panel_background(
|
|
1601
|
+
class panel_background(legend_key):
|
|
1419
1602
|
"""
|
|
1420
1603
|
Panel background
|
|
1421
1604
|
|
|
@@ -1424,6 +1607,9 @@ class panel_background(themeable):
|
|
|
1424
1607
|
theme_element : element_rect
|
|
1425
1608
|
"""
|
|
1426
1609
|
|
|
1610
|
+
def apply_figure(self, figure: Figure, targets: ThemeTargets):
|
|
1611
|
+
super().apply_figure(figure, targets)
|
|
1612
|
+
|
|
1427
1613
|
def apply_ax(self, ax: Axes):
|
|
1428
1614
|
super().apply_ax(ax)
|
|
1429
1615
|
d = self.properties
|
|
@@ -1485,11 +1671,13 @@ class plot_background(themeable):
|
|
|
1485
1671
|
|
|
1486
1672
|
def apply_figure(self, figure: Figure, targets: ThemeTargets):
|
|
1487
1673
|
super().apply_figure(figure, targets)
|
|
1488
|
-
|
|
1674
|
+
if targets.plot_background:
|
|
1675
|
+
targets.plot_background.set(**self.properties)
|
|
1489
1676
|
|
|
1490
1677
|
def blank_figure(self, figure: Figure, targets: ThemeTargets):
|
|
1491
1678
|
super().blank_figure(figure, targets)
|
|
1492
|
-
|
|
1679
|
+
if targets.plot_background:
|
|
1680
|
+
targets.plot_background.set_visible(False)
|
|
1493
1681
|
|
|
1494
1682
|
|
|
1495
1683
|
class strip_background_x(MixinSequenceOfValues):
|
|
@@ -1543,7 +1731,6 @@ class strip_background(strip_background_x, strip_background_y):
|
|
|
1543
1731
|
|
|
1544
1732
|
|
|
1545
1733
|
class rect(
|
|
1546
|
-
legend_key,
|
|
1547
1734
|
legend_frame,
|
|
1548
1735
|
legend_background,
|
|
1549
1736
|
panel_background,
|
|
@@ -1726,156 +1913,6 @@ class axis_ticks_length(axis_ticks_length_major, axis_ticks_length_minor):
|
|
|
1726
1913
|
"""
|
|
1727
1914
|
|
|
1728
1915
|
|
|
1729
|
-
class axis_ticks_pad_major_x(themeable):
|
|
1730
|
-
"""
|
|
1731
|
-
x-axis major-tick padding
|
|
1732
|
-
|
|
1733
|
-
Parameters
|
|
1734
|
-
----------
|
|
1735
|
-
theme_element : float
|
|
1736
|
-
Value in points.
|
|
1737
|
-
"""
|
|
1738
|
-
|
|
1739
|
-
def apply_ax(self, ax: Axes):
|
|
1740
|
-
super().apply_ax(ax)
|
|
1741
|
-
val = self.properties["value"]
|
|
1742
|
-
|
|
1743
|
-
for t in ax.xaxis.get_major_ticks():
|
|
1744
|
-
_val = val if t.tick1line.get_visible() else 0
|
|
1745
|
-
t.set_pad(_val)
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
class axis_ticks_pad_major_y(themeable):
|
|
1749
|
-
"""
|
|
1750
|
-
y-axis major-tick padding
|
|
1751
|
-
|
|
1752
|
-
Parameters
|
|
1753
|
-
----------
|
|
1754
|
-
theme_element : float
|
|
1755
|
-
Value in points.
|
|
1756
|
-
|
|
1757
|
-
Note
|
|
1758
|
-
----
|
|
1759
|
-
Padding is not applied when the
|
|
1760
|
-
[](`~plotnine.theme.themeables.axis_ticks_major_y`) are
|
|
1761
|
-
blank, but it does apply when the
|
|
1762
|
-
[](`~plotnine.theme.themeables.axis_ticks_length_major_y`)
|
|
1763
|
-
is zero.
|
|
1764
|
-
"""
|
|
1765
|
-
|
|
1766
|
-
def apply_ax(self, ax: Axes):
|
|
1767
|
-
super().apply_ax(ax)
|
|
1768
|
-
val = self.properties["value"]
|
|
1769
|
-
|
|
1770
|
-
for t in ax.yaxis.get_major_ticks():
|
|
1771
|
-
_val = val if t.tick1line.get_visible() else 0
|
|
1772
|
-
t.set_pad(_val)
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
class axis_ticks_pad_major(axis_ticks_pad_major_x, axis_ticks_pad_major_y):
|
|
1776
|
-
"""
|
|
1777
|
-
Axis major-tick padding
|
|
1778
|
-
|
|
1779
|
-
Parameters
|
|
1780
|
-
----------
|
|
1781
|
-
theme_element : float
|
|
1782
|
-
Value in points.
|
|
1783
|
-
|
|
1784
|
-
Note
|
|
1785
|
-
----
|
|
1786
|
-
Padding is not applied when the
|
|
1787
|
-
[](`~plotnine.theme.themeables.axis_ticks_major`) are blank,
|
|
1788
|
-
but it does apply when the
|
|
1789
|
-
[](`~plotnine.theme.themeables.axis_ticks_length_major`) is zero.
|
|
1790
|
-
"""
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
class axis_ticks_pad_minor_x(themeable):
|
|
1794
|
-
"""
|
|
1795
|
-
x-axis minor-tick padding
|
|
1796
|
-
|
|
1797
|
-
Parameters
|
|
1798
|
-
----------
|
|
1799
|
-
theme_element : float
|
|
1800
|
-
|
|
1801
|
-
Note
|
|
1802
|
-
----
|
|
1803
|
-
Padding is not applied when the
|
|
1804
|
-
[](`~plotnine.theme.themeables.axis_ticks_minor_x`) are
|
|
1805
|
-
blank, but it does apply when the
|
|
1806
|
-
[](`~plotnine.theme.themeables.axis_ticks_length_minor_x`) is zero.
|
|
1807
|
-
"""
|
|
1808
|
-
|
|
1809
|
-
def apply_ax(self, ax: Axes):
|
|
1810
|
-
super().apply_ax(ax)
|
|
1811
|
-
val = self.properties["value"]
|
|
1812
|
-
|
|
1813
|
-
for t in ax.xaxis.get_minor_ticks():
|
|
1814
|
-
_val = val if t.tick1line.get_visible() else 0
|
|
1815
|
-
t.set_pad(_val)
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
class axis_ticks_pad_minor_y(themeable):
|
|
1819
|
-
"""
|
|
1820
|
-
y-axis minor-tick padding
|
|
1821
|
-
|
|
1822
|
-
Parameters
|
|
1823
|
-
----------
|
|
1824
|
-
theme_element : float
|
|
1825
|
-
|
|
1826
|
-
Note
|
|
1827
|
-
----
|
|
1828
|
-
Padding is not applied when the
|
|
1829
|
-
[](`~plotnine.theme.themeables.axis_ticks_minor_y`) are
|
|
1830
|
-
blank, but it does apply when the
|
|
1831
|
-
[](`~plotnine.theme.themeables.axis_ticks_length_minor_y`)
|
|
1832
|
-
is zero.
|
|
1833
|
-
"""
|
|
1834
|
-
|
|
1835
|
-
def apply_ax(self, ax: Axes):
|
|
1836
|
-
super().apply_ax(ax)
|
|
1837
|
-
val = self.properties["value"]
|
|
1838
|
-
|
|
1839
|
-
for t in ax.yaxis.get_minor_ticks():
|
|
1840
|
-
_val = val if t.tick1line.get_visible() else 0
|
|
1841
|
-
t.set_pad(_val)
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
class axis_ticks_pad_minor(axis_ticks_pad_minor_x, axis_ticks_pad_minor_y):
|
|
1845
|
-
"""
|
|
1846
|
-
Axis minor-tick padding
|
|
1847
|
-
|
|
1848
|
-
Parameters
|
|
1849
|
-
----------
|
|
1850
|
-
theme_element : float
|
|
1851
|
-
|
|
1852
|
-
Note
|
|
1853
|
-
----
|
|
1854
|
-
Padding is not applied when the
|
|
1855
|
-
[](`~plotnine.theme.themeables.axis_ticks_minor`) are
|
|
1856
|
-
blank, but it does apply when the
|
|
1857
|
-
[](`~plotnine.theme.themeables.axis_ticks_length_minor`) is zero.
|
|
1858
|
-
"""
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
class axis_ticks_pad(axis_ticks_pad_major, axis_ticks_pad_minor):
|
|
1862
|
-
"""
|
|
1863
|
-
Axis tick padding
|
|
1864
|
-
|
|
1865
|
-
Parameters
|
|
1866
|
-
----------
|
|
1867
|
-
theme_element : float
|
|
1868
|
-
Value in points.
|
|
1869
|
-
|
|
1870
|
-
Note
|
|
1871
|
-
----
|
|
1872
|
-
Padding is not applied when the
|
|
1873
|
-
[](`~plotnine.theme.themeables.axis_ticks`) are blank,
|
|
1874
|
-
but it does apply when the
|
|
1875
|
-
[](`~plotnine.theme.themeables.axis_ticks_length`) is zero.
|
|
1876
|
-
"""
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
1916
|
class panel_spacing_x(themeable):
|
|
1880
1917
|
"""
|
|
1881
1918
|
Horizontal spacing between the facet panels
|
|
@@ -2535,3 +2572,166 @@ class axis_ticks_direction(axis_ticks_direction_x, axis_ticks_direction_y):
|
|
|
2535
2572
|
`in` for ticks inside the panel.
|
|
2536
2573
|
`out` for ticks outside the panel.
|
|
2537
2574
|
"""
|
|
2575
|
+
|
|
2576
|
+
|
|
2577
|
+
class axis_ticks_pad_major_x(themeable):
|
|
2578
|
+
"""
|
|
2579
|
+
x-axis major-tick padding
|
|
2580
|
+
|
|
2581
|
+
Parameters
|
|
2582
|
+
----------
|
|
2583
|
+
theme_element : float
|
|
2584
|
+
Value in points.
|
|
2585
|
+
"""
|
|
2586
|
+
|
|
2587
|
+
def apply_ax(self, ax: Axes):
|
|
2588
|
+
super().apply_ax(ax)
|
|
2589
|
+
val = self.properties["value"]
|
|
2590
|
+
|
|
2591
|
+
for t in ax.xaxis.get_major_ticks():
|
|
2592
|
+
_val = val if t.tick1line.get_visible() else 0
|
|
2593
|
+
t.set_pad(_val)
|
|
2594
|
+
|
|
2595
|
+
|
|
2596
|
+
class axis_ticks_pad_major_y(themeable):
|
|
2597
|
+
"""
|
|
2598
|
+
y-axis major-tick padding
|
|
2599
|
+
|
|
2600
|
+
Parameters
|
|
2601
|
+
----------
|
|
2602
|
+
theme_element : float
|
|
2603
|
+
Value in points.
|
|
2604
|
+
|
|
2605
|
+
Note
|
|
2606
|
+
----
|
|
2607
|
+
Padding is not applied when the
|
|
2608
|
+
[](`~plotnine.theme.themeables.axis_ticks_major_y`) are
|
|
2609
|
+
blank, but it does apply when the
|
|
2610
|
+
[](`~plotnine.theme.themeables.axis_ticks_length_major_y`)
|
|
2611
|
+
is zero.
|
|
2612
|
+
"""
|
|
2613
|
+
|
|
2614
|
+
def apply_ax(self, ax: Axes):
|
|
2615
|
+
super().apply_ax(ax)
|
|
2616
|
+
val = self.properties["value"]
|
|
2617
|
+
|
|
2618
|
+
for t in ax.yaxis.get_major_ticks():
|
|
2619
|
+
_val = val if t.tick1line.get_visible() else 0
|
|
2620
|
+
t.set_pad(_val)
|
|
2621
|
+
|
|
2622
|
+
|
|
2623
|
+
class axis_ticks_pad_major(axis_ticks_pad_major_x, axis_ticks_pad_major_y):
|
|
2624
|
+
"""
|
|
2625
|
+
Axis major-tick padding
|
|
2626
|
+
|
|
2627
|
+
Parameters
|
|
2628
|
+
----------
|
|
2629
|
+
theme_element : float
|
|
2630
|
+
Value in points.
|
|
2631
|
+
|
|
2632
|
+
Note
|
|
2633
|
+
----
|
|
2634
|
+
Padding is not applied when the
|
|
2635
|
+
[](`~plotnine.theme.themeables.axis_ticks_major`) are blank,
|
|
2636
|
+
but it does apply when the
|
|
2637
|
+
[](`~plotnine.theme.themeables.axis_ticks_length_major`) is zero.
|
|
2638
|
+
"""
|
|
2639
|
+
|
|
2640
|
+
|
|
2641
|
+
class axis_ticks_pad_minor_x(themeable):
|
|
2642
|
+
"""
|
|
2643
|
+
x-axis minor-tick padding
|
|
2644
|
+
|
|
2645
|
+
Parameters
|
|
2646
|
+
----------
|
|
2647
|
+
theme_element : float
|
|
2648
|
+
|
|
2649
|
+
Note
|
|
2650
|
+
----
|
|
2651
|
+
Padding is not applied when the
|
|
2652
|
+
[](`~plotnine.theme.themeables.axis_ticks_minor_x`) are
|
|
2653
|
+
blank, but it does apply when the
|
|
2654
|
+
[](`~plotnine.theme.themeables.axis_ticks_length_minor_x`) is zero.
|
|
2655
|
+
"""
|
|
2656
|
+
|
|
2657
|
+
def apply_ax(self, ax: Axes):
|
|
2658
|
+
super().apply_ax(ax)
|
|
2659
|
+
val = self.properties["value"]
|
|
2660
|
+
|
|
2661
|
+
for t in ax.xaxis.get_minor_ticks():
|
|
2662
|
+
_val = val if t.tick1line.get_visible() else 0
|
|
2663
|
+
t.set_pad(_val)
|
|
2664
|
+
|
|
2665
|
+
|
|
2666
|
+
class axis_ticks_pad_minor_y(themeable):
|
|
2667
|
+
"""
|
|
2668
|
+
y-axis minor-tick padding
|
|
2669
|
+
|
|
2670
|
+
Parameters
|
|
2671
|
+
----------
|
|
2672
|
+
theme_element : float
|
|
2673
|
+
|
|
2674
|
+
Note
|
|
2675
|
+
----
|
|
2676
|
+
Padding is not applied when the
|
|
2677
|
+
[](`~plotnine.theme.themeables.axis_ticks_minor_y`) are
|
|
2678
|
+
blank, but it does apply when the
|
|
2679
|
+
[](`~plotnine.theme.themeables.axis_ticks_length_minor_y`)
|
|
2680
|
+
is zero.
|
|
2681
|
+
"""
|
|
2682
|
+
|
|
2683
|
+
def apply_ax(self, ax: Axes):
|
|
2684
|
+
super().apply_ax(ax)
|
|
2685
|
+
val = self.properties["value"]
|
|
2686
|
+
|
|
2687
|
+
for t in ax.yaxis.get_minor_ticks():
|
|
2688
|
+
_val = val if t.tick1line.get_visible() else 0
|
|
2689
|
+
t.set_pad(_val)
|
|
2690
|
+
|
|
2691
|
+
|
|
2692
|
+
class axis_ticks_pad_minor(axis_ticks_pad_minor_x, axis_ticks_pad_minor_y):
|
|
2693
|
+
"""
|
|
2694
|
+
Axis minor-tick padding
|
|
2695
|
+
|
|
2696
|
+
Parameters
|
|
2697
|
+
----------
|
|
2698
|
+
theme_element : float
|
|
2699
|
+
|
|
2700
|
+
Note
|
|
2701
|
+
----
|
|
2702
|
+
Padding is not applied when the
|
|
2703
|
+
[](`~plotnine.theme.themeables.axis_ticks_minor`) are
|
|
2704
|
+
blank, but it does apply when the
|
|
2705
|
+
[](`~plotnine.theme.themeables.axis_ticks_length_minor`) is zero.
|
|
2706
|
+
"""
|
|
2707
|
+
|
|
2708
|
+
|
|
2709
|
+
class axis_ticks_pad(axis_ticks_pad_major, axis_ticks_pad_minor):
|
|
2710
|
+
"""
|
|
2711
|
+
Axis tick padding
|
|
2712
|
+
|
|
2713
|
+
Parameters
|
|
2714
|
+
----------
|
|
2715
|
+
theme_element : float
|
|
2716
|
+
Value in points.
|
|
2717
|
+
|
|
2718
|
+
Note
|
|
2719
|
+
----
|
|
2720
|
+
Padding is not applied when the
|
|
2721
|
+
[](`~plotnine.theme.themeables.axis_ticks`) are blank,
|
|
2722
|
+
but it does apply when the
|
|
2723
|
+
[](`~plotnine.theme.themeables.axis_ticks_length`) is zero.
|
|
2724
|
+
"""
|
|
2725
|
+
|
|
2726
|
+
def __init__(self, theme_element):
|
|
2727
|
+
x = theme_element
|
|
2728
|
+
msg = (
|
|
2729
|
+
f"Themeable '{self.__class__.__name__}' is deprecated and"
|
|
2730
|
+
"will be removed in a future version. "
|
|
2731
|
+
"Use the margin parameter of axis_text. e.g.\n"
|
|
2732
|
+
f"axis_text_x(margin={{'t': {x}}})\n"
|
|
2733
|
+
f"axis_text_y(margin={{'r': {x}}})\n"
|
|
2734
|
+
f"axis_text(margin={{'t': {x}, 'r': {x}}})"
|
|
2735
|
+
)
|
|
2736
|
+
warn(msg, FutureWarning, stacklevel=1)
|
|
2737
|
+
super().__init__(theme_element)
|
plotnine/typing.py
CHANGED
|
@@ -80,7 +80,7 @@ FacetSpaceRatios: TypeAlias = dict[Literal["x", "y"], Sequence[float]]
|
|
|
80
80
|
|
|
81
81
|
StripPosition: TypeAlias = Literal["top", "right"]
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
# Scales
|
|
84
84
|
|
|
85
85
|
# Name names of scaled aesthetics
|
|
86
86
|
ScaledAestheticsName: TypeAlias = Literal[
|
|
@@ -110,11 +110,11 @@ ScaledAestheticsName: TypeAlias = Literal[
|
|
|
110
110
|
"upper",
|
|
111
111
|
]
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
# Coords
|
|
114
114
|
CoordRange: TypeAlias = tuple[float, float]
|
|
115
115
|
|
|
116
116
|
# Guide
|
|
117
|
-
|
|
117
|
+
Side: TypeAlias = Literal["left", "right", "top", "bottom"]
|
|
118
118
|
LegendPosition: TypeAlias = (
|
|
119
119
|
Literal["left", "right", "top", "bottom", "inside"] | tuple[float, float]
|
|
120
120
|
)
|
plotnine/watermark.py
CHANGED
|
@@ -50,12 +50,12 @@ class watermark:
|
|
|
50
50
|
kwargs["zorder"] = 99.9
|
|
51
51
|
self.kwargs = kwargs
|
|
52
52
|
|
|
53
|
-
def __radd__(self,
|
|
53
|
+
def __radd__(self, other: p9.ggplot) -> p9.ggplot:
|
|
54
54
|
"""
|
|
55
55
|
Add watermark to ggplot object
|
|
56
56
|
"""
|
|
57
|
-
|
|
58
|
-
return
|
|
57
|
+
other.watermarks.append(self)
|
|
58
|
+
return other
|
|
59
59
|
|
|
60
60
|
def draw(self, figure: matplotlib.figure.Figure):
|
|
61
61
|
"""
|