39
39
40
40
from matplotlib .axes import Axes , SubplotBase , subplot_class_factory
41
41
from matplotlib .blocking_input import BlockingMouseInput , BlockingKeyMouseInput
42
+ from matplotlib .gridspec import GridSpec
42
43
from matplotlib .legend import Legend
43
44
from matplotlib .patches import Rectangle
44
45
from matplotlib .projections import (get_projection_names ,
@@ -1011,6 +1012,138 @@ def add_subplot(self, *args, **kwargs):
1011
1012
a .stale_callback = _stale_figure_callback
1012
1013
return a
1013
1014
1015
+ def subplots (self , nrows = 1 , ncols = 1 , sharex = False , sharey = False ,
1016
+ squeeze = True , subplot_kw = None , gridspec_kw = None ):
1017
+ """
1018
+ Add a set of subplots to this figure.
1019
+
1020
+ Parameters
1021
+ ----------
1022
+ nrows : int, default: 1
1023
+ Number of rows of the subplot grid.
1024
+
1025
+ ncols : int, default: 1
1026
+ Number of columns of the subplot grid.
1027
+
1028
+ sharex : {"none", "all", "row", "col"} or bool, default: False
1029
+ If *False*, or "none", each subplot has its own X axis.
1030
+
1031
+ If *True*, or "all", all subplots will share an X axis, and the x
1032
+ tick labels on all but the last row of plots will be invisible.
1033
+
1034
+ If "col", each subplot column will share an X axis, and the x
1035
+ tick labels on all but the last row of plots will be invisible.
1036
+
1037
+ If "row", each subplot row will share an X axis.
1038
+
1039
+ sharey : {"none", "all", "row", "col"} or bool, default: False
1040
+ If *False*, or "none", each subplot has its own Y axis.
1041
+
1042
+ If *True*, or "all", all subplots will share an Y axis, and the y
1043
+ tick labels on all but the first column of plots will be invisible.
1044
+
1045
+ If "row", each subplot row will share an Y axis, and the y tick
1046
+ labels on all but the first column of plots will be invisible.
1047
+
1048
+ If "col", each subplot column will share an Y axis.
1049
+
1050
+ squeeze : bool, default: True
1051
+ If *True*, extra dimensions are squeezed out from the returned axes
1052
+ array:
1053
+
1054
+ - if only one subplot is constructed (nrows=ncols=1), the resulting
1055
+ single Axes object is returned as a scalar.
1056
+
1057
+ - for Nx1 or 1xN subplots, the returned object is a 1-d numpy
1058
+ object array of Axes objects are returned as numpy 1-d arrays.
1059
+
1060
+ - for NxM subplots with N>1 and M>1 are returned as a 2d array.
1061
+
1062
+ If *False*, no squeezing at all is done: the returned object is
1063
+ always a 2-d array of Axes instances, even if it ends up being 1x1.
1064
+
1065
+ subplot_kw : dict, default: {}
1066
+ Dict with keywords passed to the
1067
+ :meth:`~matplotlib.figure.Figure.add_subplot` call used to create
1068
+ each subplots.
1069
+
1070
+ gridspec_kw : dict, default: {}
1071
+ Dict with keywords passed to the
1072
+ :class:`~matplotlib.gridspec.GridSpec` constructor used to create
1073
+ the grid the subplots are placed on.
1074
+
1075
+ Returns
1076
+ -------
1077
+ ax : single Axes object or array of Axes objects
1078
+ The added axes. The dimensions of the resulting array can be
1079
+ controlled with the squeeze keyword, see above.
1080
+
1081
+ See Also
1082
+ --------
1083
+ pyplot.subplots : pyplot API; docstring includes examples.
1084
+ """
1085
+
1086
+ # for backwards compatibility
1087
+ if isinstance (sharex , bool ):
1088
+ sharex = "all" if sharex else "none"
1089
+ if isinstance (sharey , bool ):
1090
+ sharey = "all" if sharey else "none"
1091
+ share_values = ["all" , "row" , "col" , "none" ]
1092
+ if sharex not in share_values :
1093
+ # This check was added because it is very easy to type
1094
+ # `subplots(1, 2, 1)` when `subplot(1, 2, 1)` was intended.
1095
+ # In most cases, no error will ever occur, but mysterious behavior
1096
+ # will result because what was intended to be the subplot index is
1097
+ # instead treated as a bool for sharex.
1098
+ if isinstance (sharex , int ):
1099
+ warnings .warn (
1100
+ "sharex argument to add_subplots() was an integer. "
1101
+ "Did you intend to use add_subplot() (without 's')?" )
1102
+
1103
+ raise ValueError ("sharex [%s] must be one of %s" %
1104
+ (sharex , share_values ))
1105
+ if sharey not in share_values :
1106
+ raise ValueError ("sharey [%s] must be one of %s" %
1107
+ (sharey , share_values ))
1108
+ if subplot_kw is None :
1109
+ subplot_kw = {}
1110
+ if gridspec_kw is None :
1111
+ gridspec_kw = {}
1112
+
1113
+ gs = GridSpec (nrows , ncols , ** gridspec_kw )
1114
+
1115
+ # Create array to hold all axes.
1116
+ axarr = np .empty ((nrows , ncols ), dtype = object )
1117
+ for row in range (nrows ):
1118
+ for col in range (ncols ):
1119
+ shared_with = {"none" : None , "all" : axarr [0 , 0 ],
1120
+ "row" : axarr [row , 0 ], "col" : axarr [0 , col ]}
1121
+ subplot_kw ["sharex" ] = shared_with [sharex ]
1122
+ subplot_kw ["sharey" ] = shared_with [sharey ]
1123
+ axarr [row , col ] = self .add_subplot (gs [row , col ], ** subplot_kw )
1124
+
1125
+ # turn off redundant tick labeling
1126
+ if sharex in ["col" , "all" ]:
1127
+ # turn off all but the bottom row
1128
+ for ax in axarr [:- 1 , :].flat :
1129
+ for label in ax .get_xticklabels ():
1130
+ label .set_visible (False )
1131
+ ax .xaxis .offsetText .set_visible (False )
1132
+ if sharey in ["row" , "all" ]:
1133
+ # turn off all but the first column
1134
+ for ax in axarr [:, 1 :].flat :
1135
+ for label in ax .get_yticklabels ():
1136
+ label .set_visible (False )
1137
+ ax .yaxis .offsetText .set_visible (False )
1138
+
1139
+ if squeeze :
1140
+ # Discarding unneeded dimensions that equal 1. If we only have one
1141
+ # subplot, just return it instead of a 1-element array.
1142
+ return axarr .item () if axarr .size == 1 else axarr .squeeze ()
1143
+ else :
1144
+ # Returned axis array will be always 2-d, even if nrows=ncols=1.
1145
+ return axarr
1146
+
1014
1147
def clf (self , keep_observers = False ):
1015
1148
"""
1016
1149
Clear the figure.
0 commit comments