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.
Files changed (92) hide show
  1. plotnine/__init__.py +31 -37
  2. plotnine/_mpl/gridspec.py +265 -0
  3. plotnine/_mpl/layout_manager/__init__.py +6 -0
  4. plotnine/_mpl/layout_manager/_engine.py +87 -0
  5. plotnine/_mpl/layout_manager/_layout_items.py +957 -0
  6. plotnine/_mpl/layout_manager/_layout_tree.py +905 -0
  7. plotnine/_mpl/layout_manager/_spaces.py +1154 -0
  8. plotnine/_mpl/patches.py +70 -34
  9. plotnine/_mpl/text.py +159 -37
  10. plotnine/_mpl/utils.py +78 -10
  11. plotnine/_utils/__init__.py +35 -9
  12. plotnine/_utils/dev.py +45 -27
  13. plotnine/_utils/yippie.py +115 -0
  14. plotnine/animation.py +1 -1
  15. plotnine/coords/coord.py +3 -3
  16. plotnine/coords/coord_trans.py +1 -1
  17. plotnine/data/__init__.py +43 -8
  18. plotnine/data/anscombe-quartet.csv +45 -0
  19. plotnine/doctools.py +2 -2
  20. plotnine/facets/facet.py +34 -43
  21. plotnine/facets/facet_grid.py +14 -6
  22. plotnine/facets/facet_wrap.py +3 -5
  23. plotnine/facets/strips.py +20 -33
  24. plotnine/geoms/annotate.py +3 -3
  25. plotnine/geoms/annotation_logticks.py +2 -0
  26. plotnine/geoms/annotation_stripes.py +2 -0
  27. plotnine/geoms/geom.py +3 -3
  28. plotnine/geoms/geom_bar.py +10 -2
  29. plotnine/geoms/geom_col.py +6 -0
  30. plotnine/geoms/geom_crossbar.py +2 -3
  31. plotnine/geoms/geom_path.py +2 -2
  32. plotnine/geoms/geom_violin.py +24 -7
  33. plotnine/ggplot.py +95 -66
  34. plotnine/guides/guide.py +19 -20
  35. plotnine/guides/guide_colorbar.py +6 -6
  36. plotnine/guides/guide_legend.py +15 -16
  37. plotnine/guides/guides.py +8 -8
  38. plotnine/helpers.py +49 -0
  39. plotnine/iapi.py +33 -7
  40. plotnine/labels.py +8 -3
  41. plotnine/layer.py +4 -4
  42. plotnine/mapping/_env.py +2 -2
  43. plotnine/mapping/_eval_environment.py +85 -0
  44. plotnine/mapping/aes.py +14 -30
  45. plotnine/mapping/evaluation.py +7 -65
  46. plotnine/options.py +14 -7
  47. plotnine/plot_composition/__init__.py +10 -0
  48. plotnine/plot_composition/_compose.py +462 -0
  49. plotnine/plot_composition/_plotspec.py +50 -0
  50. plotnine/plot_composition/_spacer.py +32 -0
  51. plotnine/positions/position_dodge.py +1 -1
  52. plotnine/positions/position_dodge2.py +1 -1
  53. plotnine/positions/position_stack.py +1 -2
  54. plotnine/qplot.py +1 -2
  55. plotnine/scales/__init__.py +0 -6
  56. plotnine/scales/limits.py +7 -7
  57. plotnine/scales/scale.py +4 -4
  58. plotnine/scales/scale_continuous.py +2 -1
  59. plotnine/scales/scale_identity.py +10 -2
  60. plotnine/scales/scale_manual.py +6 -2
  61. plotnine/stats/binning.py +5 -2
  62. plotnine/stats/smoothers.py +3 -5
  63. plotnine/stats/stat.py +3 -3
  64. plotnine/stats/stat_bindot.py +1 -3
  65. plotnine/stats/stat_density.py +2 -2
  66. plotnine/stats/stat_qq_line.py +1 -1
  67. plotnine/stats/stat_sina.py +34 -1
  68. plotnine/themes/elements/__init__.py +3 -0
  69. plotnine/themes/elements/element_text.py +35 -24
  70. plotnine/themes/elements/margin.py +137 -61
  71. plotnine/themes/targets.py +3 -1
  72. plotnine/themes/theme.py +21 -7
  73. plotnine/themes/theme_538.py +0 -1
  74. plotnine/themes/theme_bw.py +0 -1
  75. plotnine/themes/theme_dark.py +0 -1
  76. plotnine/themes/theme_gray.py +32 -34
  77. plotnine/themes/theme_light.py +1 -1
  78. plotnine/themes/theme_matplotlib.py +28 -31
  79. plotnine/themes/theme_seaborn.py +36 -36
  80. plotnine/themes/theme_void.py +25 -27
  81. plotnine/themes/theme_xkcd.py +0 -1
  82. plotnine/themes/themeable.py +369 -169
  83. plotnine/typing.py +3 -3
  84. plotnine/watermark.py +3 -3
  85. {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info}/METADATA +8 -5
  86. {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info}/RECORD +89 -78
  87. {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info}/WHEEL +1 -1
  88. plotnine/_mpl/_plot_side_space.py +0 -888
  89. plotnine/_mpl/_plotnine_tight_layout.py +0 -293
  90. plotnine/_mpl/layout_engine.py +0 -110
  91. {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info/licenses}/LICENSE +0 -0
  92. {plotnine-0.14.5.dist-info → plotnine-0.15.0a2.dist-info}/top_level.txt +0 -0
@@ -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(axis_title, legend_title, plot_title, plot_subtitle, plot_caption):
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
- self.set(ax.get_xticklabels())
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.set_tick_params(
806
- which="both", labelbottom=False, labeltop=False
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
- self.set(ax.get_yticklabels())
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.set_tick_params(
828
- which="both", labelleft=False, labelright=False
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("left", False):
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 properties.get("edgecolor") in ("none", "None"):
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(themeable):
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
- figure.patch.set(**self.properties)
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
- figure.patch.set_visible(False)
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
- ## Scales
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
- ## Coords
113
+ # Coords
114
114
  CoordRange: TypeAlias = tuple[float, float]
115
115
 
116
116
  # Guide
117
- SidePosition: TypeAlias = Literal["left", "right", "top", "bottom"]
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, plot: p9.ggplot) -> p9.ggplot:
53
+ def __radd__(self, other: p9.ggplot) -> p9.ggplot:
54
54
  """
55
55
  Add watermark to ggplot object
56
56
  """
57
- plot.watermarks.append(self)
58
- return plot
57
+ other.watermarks.append(self)
58
+ return other
59
59
 
60
60
  def draw(self, figure: matplotlib.figure.Figure):
61
61
  """