|
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