Coverage for /usr/lib/python3/dist-packages/matplotlib/projections/__init__.py: 89%

28 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1""" 

2Non-separable transforms that map from data space to screen space. 

3 

4Projections are defined as `~.axes.Axes` subclasses. They include the 

5following elements: 

6 

7- A transformation from data coordinates into display coordinates. 

8 

9- An inverse of that transformation. This is used, for example, to convert 

10 mouse positions from screen space back into data space. 

11 

12- Transformations for the gridlines, ticks and ticklabels. Custom projections 

13 will often need to place these elements in special locations, and Matplotlib 

14 has a facility to help with doing so. 

15 

16- Setting up default values (overriding `~.axes.Axes.cla`), since the defaults 

17 for a rectilinear axes may not be appropriate. 

18 

19- Defining the shape of the axes, for example, an elliptical axes, that will be 

20 used to draw the background of the plot and for clipping any data elements. 

21 

22- Defining custom locators and formatters for the projection. For example, in 

23 a geographic projection, it may be more convenient to display the grid in 

24 degrees, even if the data is in radians. 

25 

26- Set up interactive panning and zooming. This is left as an "advanced" 

27 feature left to the reader, but there is an example of this for polar plots 

28 in `matplotlib.projections.polar`. 

29 

30- Any additional methods for additional convenience or features. 

31 

32Once the projection axes is defined, it can be used in one of two ways: 

33 

34- By defining the class attribute ``name``, the projection axes can be 

35 registered with `matplotlib.projections.register_projection` and subsequently 

36 simply invoked by name:: 

37 

38 fig.add_subplot(projection="my_proj_name") 

39 

40- For more complex, parameterisable projections, a generic "projection" object 

41 may be defined which includes the method ``_as_mpl_axes``. ``_as_mpl_axes`` 

42 should take no arguments and return the projection's axes subclass and a 

43 dictionary of additional arguments to pass to the subclass' ``__init__`` 

44 method. Subsequently a parameterised projection can be initialised with:: 

45 

46 fig.add_subplot(projection=MyProjection(param1=param1_value)) 

47 

48 where MyProjection is an object which implements a ``_as_mpl_axes`` method. 

49 

50A full-fledged and heavily annotated example is in 

51:doc:`/gallery/misc/custom_projection`. The polar plot functionality in 

52`matplotlib.projections.polar` may also be of interest. 

53""" 

54 

55from .. import axes, _docstring 

56from .geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes 

57from .polar import PolarAxes 

58from mpl_toolkits.mplot3d import Axes3D 

59 

60 

61class ProjectionRegistry: 

62 """A mapping of registered projection names to projection classes.""" 

63 

64 def __init__(self): 

65 self._all_projection_types = {} 

66 

67 def register(self, *projections): 

68 """Register a new set of projections.""" 

69 for projection in projections: 

70 name = projection.name 

71 self._all_projection_types[name] = projection 

72 

73 def get_projection_class(self, name): 

74 """Get a projection class from its *name*.""" 

75 return self._all_projection_types[name] 

76 

77 def get_projection_names(self): 

78 """Return the names of all projections currently registered.""" 

79 return sorted(self._all_projection_types) 

80 

81 

82projection_registry = ProjectionRegistry() 

83projection_registry.register( 

84 axes.Axes, 

85 PolarAxes, 

86 AitoffAxes, 

87 HammerAxes, 

88 LambertAxes, 

89 MollweideAxes, 

90 Axes3D, 

91) 

92 

93 

94def register_projection(cls): 

95 projection_registry.register(cls) 

96 

97 

98def get_projection_class(projection=None): 

99 """ 

100 Get a projection class from its name. 

101 

102 If *projection* is None, a standard rectilinear projection is returned. 

103 """ 

104 if projection is None: 

105 projection = 'rectilinear' 

106 

107 try: 

108 return projection_registry.get_projection_class(projection) 

109 except KeyError as err: 

110 raise ValueError("Unknown projection %r" % projection) from err 

111 

112 

113get_projection_names = projection_registry.get_projection_names 

114_docstring.interpd.update(projection_names=get_projection_names())