plotnine 0.14.5__py3-none-any.whl → 0.15.0.dev2__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 (64) 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 +916 -0
  6. plotnine/_mpl/layout_manager/_layout_tree.py +625 -0
  7. plotnine/_mpl/layout_manager/_spaces.py +1007 -0
  8. plotnine/_mpl/patches.py +1 -1
  9. plotnine/_mpl/text.py +59 -24
  10. plotnine/_mpl/utils.py +78 -10
  11. plotnine/_utils/__init__.py +5 -5
  12. plotnine/_utils/dev.py +45 -27
  13. plotnine/animation.py +1 -1
  14. plotnine/coords/coord_trans.py +1 -1
  15. plotnine/data/__init__.py +12 -8
  16. plotnine/doctools.py +1 -1
  17. plotnine/facets/facet.py +30 -39
  18. plotnine/facets/facet_grid.py +14 -6
  19. plotnine/facets/facet_wrap.py +3 -5
  20. plotnine/facets/strips.py +7 -9
  21. plotnine/geoms/geom_crossbar.py +2 -3
  22. plotnine/geoms/geom_path.py +1 -1
  23. plotnine/ggplot.py +94 -65
  24. plotnine/guides/guide.py +12 -10
  25. plotnine/guides/guide_colorbar.py +3 -3
  26. plotnine/guides/guide_legend.py +12 -13
  27. plotnine/guides/guides.py +3 -3
  28. plotnine/iapi.py +5 -2
  29. plotnine/labels.py +5 -0
  30. plotnine/mapping/aes.py +4 -3
  31. plotnine/options.py +14 -7
  32. plotnine/plot_composition/__init__.py +10 -0
  33. plotnine/plot_composition/_compose.py +436 -0
  34. plotnine/plot_composition/_plotspec.py +50 -0
  35. plotnine/plot_composition/_spacer.py +32 -0
  36. plotnine/positions/position_dodge.py +1 -1
  37. plotnine/positions/position_dodge2.py +1 -1
  38. plotnine/positions/position_stack.py +1 -2
  39. plotnine/qplot.py +1 -2
  40. plotnine/scales/__init__.py +0 -6
  41. plotnine/scales/scale.py +1 -1
  42. plotnine/stats/binning.py +1 -1
  43. plotnine/stats/smoothers.py +3 -5
  44. plotnine/stats/stat_density.py +1 -1
  45. plotnine/stats/stat_qq_line.py +1 -1
  46. plotnine/stats/stat_sina.py +1 -1
  47. plotnine/themes/elements/__init__.py +2 -0
  48. plotnine/themes/elements/element_text.py +35 -24
  49. plotnine/themes/elements/margin.py +73 -60
  50. plotnine/themes/targets.py +3 -1
  51. plotnine/themes/theme.py +13 -7
  52. plotnine/themes/theme_gray.py +28 -31
  53. plotnine/themes/theme_matplotlib.py +25 -28
  54. plotnine/themes/theme_seaborn.py +31 -34
  55. plotnine/themes/theme_void.py +17 -26
  56. plotnine/themes/themeable.py +290 -157
  57. {plotnine-0.14.5.dist-info → plotnine-0.15.0.dev2.dist-info}/METADATA +4 -3
  58. {plotnine-0.14.5.dist-info → plotnine-0.15.0.dev2.dist-info}/RECORD +61 -54
  59. {plotnine-0.14.5.dist-info → plotnine-0.15.0.dev2.dist-info}/WHEEL +1 -1
  60. plotnine/_mpl/_plot_side_space.py +0 -888
  61. plotnine/_mpl/_plotnine_tight_layout.py +0 -293
  62. plotnine/_mpl/layout_engine.py +0 -110
  63. {plotnine-0.14.5.dist-info → plotnine-0.15.0.dev2.dist-info/licenses}/LICENSE +0 -0
  64. {plotnine-0.14.5.dist-info → plotnine-0.15.0.dev2.dist-info}/top_level.txt +0 -0
@@ -719,6 +719,89 @@ class plot_caption(themeable):
719
719
  text.set_visible(False)
720
720
 
721
721
 
722
+ class plot_tag(themeable):
723
+ """
724
+ Plot tag
725
+
726
+ Parameters
727
+ ----------
728
+ theme_element : element_text
729
+
730
+ Notes
731
+ -----
732
+ The `ha` & `va` of element_text will only have an effect if the
733
+ have no effect if the
734
+ [](:class:`~plotnine.themes.themeable.plot_tag_position`)
735
+ is given as x-y coordinates.
736
+ """
737
+
738
+ _omit = ["margin"]
739
+
740
+ def apply_figure(self, figure: Figure, targets: ThemeTargets):
741
+ super().apply_figure(figure, targets)
742
+ if text := targets.plot_tag:
743
+ text.set(**self.properties)
744
+
745
+ def blank_figure(self, figure: Figure, targets: ThemeTargets):
746
+ super().blank_figure(figure, targets)
747
+ if text := targets.plot_tag:
748
+ text.set_visible(False)
749
+
750
+
751
+ class plot_title_position(themeable):
752
+ """
753
+ How to align the plot title and plot subtitle
754
+
755
+ Parameters
756
+ ----------
757
+ theme_element : Literal["panel", "plot"], default = "panel"
758
+ If "panel", the title / subtitle are aligned with respect
759
+ to the panels. If "plot", they are aligned with the plot,
760
+ excluding the margin space
761
+ """
762
+
763
+
764
+ class plot_caption_position(themeable):
765
+ """
766
+ How to align the plot caption
767
+
768
+ Parameters
769
+ ----------
770
+ theme_element : Literal["panel", "plot"], default = "panel"
771
+ If "panel", the caption is aligned with respect to the
772
+ panels. If "plot", it is aligned with the plot, excluding
773
+ the margin space.
774
+ """
775
+
776
+
777
+ class plot_tag_location(themeable):
778
+ """
779
+ The area where the tag will be positioned
780
+
781
+ Parameters
782
+ ----------
783
+ theme_element : Literal["margin", "plot", "panel"], default = "margin"
784
+ If "margin", it is placed within the plot_margin.
785
+ If "plot", it is placed in the figure, ignoring any margins.
786
+ If "panel", it is placed within the panel area.
787
+ """
788
+
789
+
790
+ class plot_tag_position(themeable):
791
+ """
792
+ Position of the tag
793
+
794
+ Parameters
795
+ ----------
796
+ theme_element : Literal["topleft", "top", "topright", "left" \
797
+ "right", "bottomleft", "bottom", "bottomleft"] \
798
+ | tuple[float, float], default = "topleft"
799
+ If the value is a string, the tag will be managed by the layout
800
+ manager. If it is a tuple of (x, y) coordinates, they should be
801
+ in figure space and the tag will be ignored by the layout manager.
802
+ """
803
+
804
+
722
805
  class strip_text_x(MixinSequenceOfValues):
723
806
  """
724
807
  Facet labels along the horizontal axis
@@ -728,7 +811,7 @@ class strip_text_x(MixinSequenceOfValues):
728
811
  theme_element : element_text
729
812
  """
730
813
 
731
- _omit = ["margin"]
814
+ _omit = ["margin", "ha"]
732
815
 
733
816
  def apply_figure(self, figure: Figure, targets: ThemeTargets):
734
817
  super().apply_figure(figure, targets)
@@ -751,7 +834,7 @@ class strip_text_y(MixinSequenceOfValues):
751
834
  theme_element : element_text
752
835
  """
753
836
 
754
- _omit = ["margin"]
837
+ _omit = ["margin", "va"]
755
838
 
756
839
  def apply_figure(self, figure: Figure, targets: ThemeTargets):
757
840
  super().apply_figure(figure, targets)
@@ -775,7 +858,9 @@ class strip_text(strip_text_x, strip_text_y):
775
858
  """
776
859
 
777
860
 
778
- class title(axis_title, legend_title, plot_title, plot_subtitle, plot_caption):
861
+ class title(
862
+ axis_title, legend_title, plot_title, plot_subtitle, plot_caption, plot_tag
863
+ ):
779
864
  """
780
865
  All titles on the plot
781
866
 
@@ -792,9 +877,20 @@ class axis_text_x(MixinSequenceOfValues):
792
877
  Parameters
793
878
  ----------
794
879
  theme_element : element_text
880
+
881
+ Notes
882
+ -----
883
+ Use the `margin` to control the gap between the ticks and the
884
+ text. e.g.
885
+
886
+ ```python
887
+ theme(axis_text_x=element_text(margin={"t": 5, "units": "pt"}))
888
+ ```
889
+
890
+ creates a margin of 5 points.
795
891
  """
796
892
 
797
- _omit = ["margin"]
893
+ _omit = ["margin", "va"]
798
894
 
799
895
  def apply_ax(self, ax: Axes):
800
896
  super().apply_ax(ax)
@@ -814,9 +910,20 @@ class axis_text_y(MixinSequenceOfValues):
814
910
  Parameters
815
911
  ----------
816
912
  theme_element : element_text
913
+
914
+ Notes
915
+ -----
916
+ Use the `margin` to control the gap between the ticks and the
917
+ text. e.g.
918
+
919
+ ```python
920
+ theme(axis_text_y=element_text(margin={"r": 5, "units": "pt"}))
921
+ ```
922
+
923
+ creates a margin of 5 points.
817
924
  """
818
925
 
819
- _omit = ["margin"]
926
+ _omit = ["margin", "ha"]
820
927
 
821
928
  def apply_ax(self, ax: Axes):
822
929
  super().apply_ax(ax)
@@ -836,6 +943,17 @@ class axis_text(axis_text_x, axis_text_y):
836
943
  Parameters
837
944
  ----------
838
945
  theme_element : element_text
946
+
947
+ Notes
948
+ -----
949
+ Use the `margin` to control the gap between the ticks and the
950
+ text. e.g.
951
+
952
+ ```python
953
+ theme(axis_text=element_text(margin={"t": 5, "r": 5, "units": "pt"}))
954
+ ```
955
+
956
+ creates a margin of 5 points.
839
957
  """
840
958
 
841
959
 
@@ -1485,11 +1603,13 @@ class plot_background(themeable):
1485
1603
 
1486
1604
  def apply_figure(self, figure: Figure, targets: ThemeTargets):
1487
1605
  super().apply_figure(figure, targets)
1488
- figure.patch.set(**self.properties)
1606
+ if targets.plot_background:
1607
+ targets.plot_background.set(**self.properties)
1489
1608
 
1490
1609
  def blank_figure(self, figure: Figure, targets: ThemeTargets):
1491
1610
  super().blank_figure(figure, targets)
1492
- figure.patch.set_visible(False)
1611
+ if targets.plot_background:
1612
+ targets.plot_background.set_visible(False)
1493
1613
 
1494
1614
 
1495
1615
  class strip_background_x(MixinSequenceOfValues):
@@ -1726,156 +1846,6 @@ class axis_ticks_length(axis_ticks_length_major, axis_ticks_length_minor):
1726
1846
  """
1727
1847
 
1728
1848
 
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
1849
  class panel_spacing_x(themeable):
1880
1850
  """
1881
1851
  Horizontal spacing between the facet panels
@@ -2535,3 +2505,166 @@ class axis_ticks_direction(axis_ticks_direction_x, axis_ticks_direction_y):
2535
2505
  `in` for ticks inside the panel.
2536
2506
  `out` for ticks outside the panel.
2537
2507
  """
2508
+
2509
+
2510
+ class axis_ticks_pad_major_x(themeable):
2511
+ """
2512
+ x-axis major-tick padding
2513
+
2514
+ Parameters
2515
+ ----------
2516
+ theme_element : float
2517
+ Value in points.
2518
+ """
2519
+
2520
+ def apply_ax(self, ax: Axes):
2521
+ super().apply_ax(ax)
2522
+ val = self.properties["value"]
2523
+
2524
+ for t in ax.xaxis.get_major_ticks():
2525
+ _val = val if t.tick1line.get_visible() else 0
2526
+ t.set_pad(_val)
2527
+
2528
+
2529
+ class axis_ticks_pad_major_y(themeable):
2530
+ """
2531
+ y-axis major-tick padding
2532
+
2533
+ Parameters
2534
+ ----------
2535
+ theme_element : float
2536
+ Value in points.
2537
+
2538
+ Note
2539
+ ----
2540
+ Padding is not applied when the
2541
+ [](`~plotnine.theme.themeables.axis_ticks_major_y`) are
2542
+ blank, but it does apply when the
2543
+ [](`~plotnine.theme.themeables.axis_ticks_length_major_y`)
2544
+ is zero.
2545
+ """
2546
+
2547
+ def apply_ax(self, ax: Axes):
2548
+ super().apply_ax(ax)
2549
+ val = self.properties["value"]
2550
+
2551
+ for t in ax.yaxis.get_major_ticks():
2552
+ _val = val if t.tick1line.get_visible() else 0
2553
+ t.set_pad(_val)
2554
+
2555
+
2556
+ class axis_ticks_pad_major(axis_ticks_pad_major_x, axis_ticks_pad_major_y):
2557
+ """
2558
+ Axis major-tick padding
2559
+
2560
+ Parameters
2561
+ ----------
2562
+ theme_element : float
2563
+ Value in points.
2564
+
2565
+ Note
2566
+ ----
2567
+ Padding is not applied when the
2568
+ [](`~plotnine.theme.themeables.axis_ticks_major`) are blank,
2569
+ but it does apply when the
2570
+ [](`~plotnine.theme.themeables.axis_ticks_length_major`) is zero.
2571
+ """
2572
+
2573
+
2574
+ class axis_ticks_pad_minor_x(themeable):
2575
+ """
2576
+ x-axis minor-tick padding
2577
+
2578
+ Parameters
2579
+ ----------
2580
+ theme_element : float
2581
+
2582
+ Note
2583
+ ----
2584
+ Padding is not applied when the
2585
+ [](`~plotnine.theme.themeables.axis_ticks_minor_x`) are
2586
+ blank, but it does apply when the
2587
+ [](`~plotnine.theme.themeables.axis_ticks_length_minor_x`) is zero.
2588
+ """
2589
+
2590
+ def apply_ax(self, ax: Axes):
2591
+ super().apply_ax(ax)
2592
+ val = self.properties["value"]
2593
+
2594
+ for t in ax.xaxis.get_minor_ticks():
2595
+ _val = val if t.tick1line.get_visible() else 0
2596
+ t.set_pad(_val)
2597
+
2598
+
2599
+ class axis_ticks_pad_minor_y(themeable):
2600
+ """
2601
+ y-axis minor-tick padding
2602
+
2603
+ Parameters
2604
+ ----------
2605
+ theme_element : float
2606
+
2607
+ Note
2608
+ ----
2609
+ Padding is not applied when the
2610
+ [](`~plotnine.theme.themeables.axis_ticks_minor_y`) are
2611
+ blank, but it does apply when the
2612
+ [](`~plotnine.theme.themeables.axis_ticks_length_minor_y`)
2613
+ is zero.
2614
+ """
2615
+
2616
+ def apply_ax(self, ax: Axes):
2617
+ super().apply_ax(ax)
2618
+ val = self.properties["value"]
2619
+
2620
+ for t in ax.yaxis.get_minor_ticks():
2621
+ _val = val if t.tick1line.get_visible() else 0
2622
+ t.set_pad(_val)
2623
+
2624
+
2625
+ class axis_ticks_pad_minor(axis_ticks_pad_minor_x, axis_ticks_pad_minor_y):
2626
+ """
2627
+ Axis minor-tick padding
2628
+
2629
+ Parameters
2630
+ ----------
2631
+ theme_element : float
2632
+
2633
+ Note
2634
+ ----
2635
+ Padding is not applied when the
2636
+ [](`~plotnine.theme.themeables.axis_ticks_minor`) are
2637
+ blank, but it does apply when the
2638
+ [](`~plotnine.theme.themeables.axis_ticks_length_minor`) is zero.
2639
+ """
2640
+
2641
+
2642
+ class axis_ticks_pad(axis_ticks_pad_major, axis_ticks_pad_minor):
2643
+ """
2644
+ Axis tick padding
2645
+
2646
+ Parameters
2647
+ ----------
2648
+ theme_element : float
2649
+ Value in points.
2650
+
2651
+ Note
2652
+ ----
2653
+ Padding is not applied when the
2654
+ [](`~plotnine.theme.themeables.axis_ticks`) are blank,
2655
+ but it does apply when the
2656
+ [](`~plotnine.theme.themeables.axis_ticks_length`) is zero.
2657
+ """
2658
+
2659
+ def __init__(self, theme_element):
2660
+ x = theme_element
2661
+ msg = (
2662
+ f"Themeable '{self.__class__.__name__}' is deprecated and"
2663
+ "will be removed in a future version. "
2664
+ "Use the margin parameter of axis_text. e.g.\n"
2665
+ f"axis_text_x(margin={{'t': {x}}})\n"
2666
+ f"axis_text_y(margin={{'r': {x}}})\n"
2667
+ f"axis_text(margin={{'t': {x}, 'r': {x}}})"
2668
+ )
2669
+ warn(msg, FutureWarning, stacklevel=1)
2670
+ super().__init__(theme_element)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: plotnine
3
- Version: 0.14.5
3
+ Version: 0.15.0.dev2
4
4
  Summary: A Grammar of Graphics for Python
5
5
  Author-email: Hassan Kibirige <has2k1@gmail.com>
6
6
  License: The MIT License (MIT)
@@ -80,9 +80,10 @@ Requires-Dist: twine; extra == "dev"
80
80
  Requires-Dist: plotnine[typing]; extra == "dev"
81
81
  Requires-Dist: pre-commit; extra == "dev"
82
82
  Provides-Extra: typing
83
- Requires-Dist: pyright==1.1.391; extra == "typing"
83
+ Requires-Dist: pyright==1.1.396; extra == "typing"
84
84
  Requires-Dist: ipython; extra == "typing"
85
85
  Requires-Dist: pandas-stubs; extra == "typing"
86
+ Dynamic: license-file
86
87
 
87
88
  # plotnine <img width="20%" align="right" src="https://github.com/has2k1/plotnine/blob/logos/doc/images/logo-512.png?raw=true">
88
89