@@ -1727,15 +1727,15 @@ def hexbin(self, x, y, C=None, reduce_C_function=None, gridsize=None, **kwargs):
1727
1727
_backends = {}
1728
1728
1729
1729
1730
- def _find_backend (backend : str ):
1730
+ def _load_backend (backend : str ):
1731
1731
"""
1732
- Find a pandas plotting backend.
1732
+ Load a pandas plotting backend.
1733
1733
1734
1734
Parameters
1735
1735
----------
1736
1736
backend : str
1737
1737
The identifier for the backend. Either an entrypoint item registered
1738
- with pkg_resources, or a module name.
1738
+ with pkg_resources, "matplotlib", or a module name.
1739
1739
1740
1740
Notes
1741
1741
-----
@@ -1746,32 +1746,45 @@ def _find_backend(backend: str):
1746
1746
types.ModuleType
1747
1747
The imported backend.
1748
1748
"""
1749
- import pkg_resources # Delay import for performance.
1750
-
1751
- for entry_point in pkg_resources .iter_entry_points ("pandas_plotting_backends" ):
1752
- if entry_point .name == backend :
1753
- _backends [entry_point .name ] = entry_point .load ()
1754
-
1755
- try :
1756
- return _backends [backend ]
1757
- except KeyError :
1758
- # Fall back to unregistered, module name approach.
1749
+ if backend == "matplotlib" :
1750
+ # Because matplotlib is an optional dependency and first-party backend,
1751
+ # we need to attempt an import here to raise an ImportError if needed.
1759
1752
try :
1760
- module = importlib . import_module ( backend )
1753
+ import pandas . plotting . _matplotlib as module
1761
1754
except ImportError :
1762
- # We re-raise later on.
1763
- pass
1764
- else :
1765
- if hasattr (module , "plot" ):
1766
- # Validate that the interface is implemented when the option
1767
- # is set, rather than at plot time.
1768
- _backends [backend ] = module
1769
- return module
1755
+ raise ImportError (
1756
+ "matplotlib is required for plotting when the "
1757
+ 'default backend "matplotlib" is selected.'
1758
+ ) from None
1759
+
1760
+ else :
1761
+ module = None
1762
+ # Delay import for performance.
1763
+ # TODO: replace with `importlib.metadata` when python_requires >= 3.8.
1764
+ from pkg_resources import iter_entry_points
1765
+
1766
+ for entry_point in iter_entry_points ("pandas_plotting_backends" ):
1767
+ if entry_point .name == backend :
1768
+ module = entry_point .load ()
1769
+
1770
+ if module is None :
1771
+ # Fall back to unregistered, module name approach.
1772
+ try :
1773
+ module = importlib .import_module (backend )
1774
+ except ImportError :
1775
+ # We re-raise later on.
1776
+ pass
1777
+
1778
+ if hasattr (module , "plot" ):
1779
+ # Validate that the interface is implemented when the option is set,
1780
+ # rather than at plot time.
1781
+ _backends [backend ] = module
1782
+ return module
1770
1783
1771
1784
raise ValueError (
1772
- f"Could not find plotting backend '{ backend } '. Ensure that you've installed "
1773
- f"the package providing the '{ backend } ' entrypoint, or that the package has a "
1774
- "top-level `.plot` method."
1785
+ f"Could not find plotting backend '{ backend } '. Ensure that you've "
1786
+ f"installed the package providing the '{ backend } ' entrypoint, or that "
1787
+ "the package has a top-level `.plot` method."
1775
1788
)
1776
1789
1777
1790
@@ -1795,19 +1808,4 @@ def _get_plot_backend(backend: str | None = None):
1795
1808
if backend in _backends :
1796
1809
return _backends [backend ]
1797
1810
1798
- if backend == "matplotlib" :
1799
- # Because matplotlib is an optional dependency and first-party backend,
1800
- # we need to attempt an import here to raise an ImportError if needed.
1801
- try :
1802
- import pandas .plotting ._matplotlib as module
1803
- except ImportError :
1804
- raise ImportError (
1805
- "matplotlib is required for plotting when the "
1806
- 'default backend "matplotlib" is selected.'
1807
- ) from None
1808
-
1809
- _backends ["matplotlib" ] = module
1810
- return module
1811
-
1812
- module = _find_backend (backend )
1813
- return module
1811
+ return _load_backend (backend )
0 commit comments