@@ -380,6 +380,12 @@ def __init__(self,
380380 self .clf ()
381381 self ._cachedRenderer = None
382382
383+ # groupers to keep track of x and y labels we want to align.
384+ # see self.align_xlabels and self.align_ylabels and
385+ # axis._get_tick_boxes_siblings
386+ self ._align_xlabel_grp = cbook .Grouper ()
387+ self ._align_ylabel_grp = cbook .Grouper ()
388+
383389 @property
384390 @cbook .deprecated ("2.1" , alternative = "Figure.patch" )
385391 def figurePatch (self ):
@@ -2084,6 +2090,165 @@ def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None,
20842090 pad = pad , h_pad = h_pad , w_pad = w_pad , rect = rect )
20852091 self .subplots_adjust (** kwargs )
20862092
2093+ def align_xlabels (self , axs = None ):
2094+ """
2095+ Align the ylabels of subplots in the same subplot column if label
2096+ alignment is being done automatically (i.e. the label position is
2097+ not manually set).
2098+
2099+ Alignment persists for draw events after this is called.
2100+
2101+ If a label is on the bottom, it is aligned with labels on axes that
2102+ also have their label on the bottom and that have the same
2103+ bottom-most subplot row. If the label is on the top,
2104+ it is aligned with labels on axes with the same top-most row.
2105+
2106+ Parameters
2107+ ----------
2108+ axs : list of `~matplotlib.axes.Axes` (None)
2109+ Optional list of (or ndarray) `~matplotlib.axes.Axes` to align
2110+ the xlabels. Default is to align all axes on the figure.
2111+
2112+ Note
2113+ ----
2114+ This assumes that ``axs`` are from the same `~.GridSpec`, so that
2115+ their `~.SubplotSpec` positions correspond to figure positions.
2116+
2117+ See Also
2118+ --------
2119+ matplotlib.figure.Figure.align_ylabels
2120+
2121+ matplotlib.figure.Figure.align_labels
2122+
2123+ Example
2124+ -------
2125+ Example with rotated xtick labels::
2126+
2127+ fig, axs = plt.subplots(1, 2)
2128+ for tick in axs[0].get_xticklabels():
2129+ tick.set_rotation(55)
2130+ axs[0].set_xlabel('XLabel 0')
2131+ axs[1].set_xlabel('XLabel 1')
2132+ fig.align_xlabels()
2133+
2134+ """
2135+
2136+ if axs is None :
2137+ axs = self .axes
2138+ axs = np .asarray (axs ).ravel ()
2139+ for ax in axs :
2140+ _log .debug (' Working on: %s' , ax .get_xlabel ())
2141+ ss = ax .get_subplotspec ()
2142+ nrows , ncols , row0 , row1 , col0 , col1 = ss .get_rows_columns ()
2143+ labpo = ax .xaxis .get_label_position () # top or bottom
2144+
2145+ # loop through other axes, and search for label positions
2146+ # that are same as this one, and that share the appropriate
2147+ # row number.
2148+ # Add to a grouper associated with each axes of sibblings.
2149+ # This list is inspected in `axis.draw` by
2150+ # `axis._update_label_position`.
2151+ for axc in axs :
2152+ if axc .xaxis .get_label_position () == labpo :
2153+ ss = axc .get_subplotspec ()
2154+ nrows , ncols , rowc0 , rowc1 , colc , col1 = \
2155+ ss .get_rows_columns ()
2156+ if (labpo == 'bottom' and rowc1 == row1 or
2157+ labpo == 'top' and rowc0 == row0 ):
2158+ # grouper for groups of xlabels to align
2159+ self ._align_xlabel_grp .join (ax , axc )
2160+
2161+ def align_ylabels (self , axs = None ):
2162+ """
2163+ Align the ylabels of subplots in the same subplot column if label
2164+ alignment is being done automatically (i.e. the label position is
2165+ not manually set).
2166+
2167+ Alignment persists for draw events after this is called.
2168+
2169+ If a label is on the left, it is aligned with labels on axes that
2170+ also have their label on the left and that have the same
2171+ left-most subplot column. If the label is on the right,
2172+ it is aligned with labels on axes with the same right-most column.
2173+
2174+ Parameters
2175+ ----------
2176+ axs : list of `~matplotlib.axes.Axes` (None)
2177+ Optional list (or ndarray) of `~matplotlib.axes.Axes` to align
2178+ the ylabels. Default is to align all axes on the figure.
2179+
2180+ Note
2181+ ----
2182+ This assumes that ``axs`` are from the same `~.GridSpec`, so that
2183+ their `~.SubplotSpec` positions correspond to figure positions.
2184+
2185+ See Also
2186+ --------
2187+ matplotlib.figure.Figure.align_xlabels
2188+
2189+ matplotlib.figure.Figure.align_labels
2190+
2191+ Example
2192+ -------
2193+ Example with large yticks labels::
2194+
2195+ fig, axs = plt.subplots(2, 1)
2196+ axs[0].plot(np.arange(0, 1000, 50))
2197+ axs[0].set_ylabel('YLabel 0')
2198+ axs[1].set_ylabel('YLabel 1')
2199+ fig.align_ylabels()
2200+
2201+ """
2202+
2203+ if axs is None :
2204+ axs = self .axes
2205+ axs = np .asarray (axs ).ravel ()
2206+ for ax in axs :
2207+ _log .debug (' Working on: %s' , ax .get_ylabel ())
2208+ ss = ax .get_subplotspec ()
2209+ nrows , ncols , row0 , row1 , col0 , col1 = ss .get_rows_columns ()
2210+ same = [ax ]
2211+ labpo = ax .yaxis .get_label_position () # left or right
2212+ # loop through other axes, and search for label positions
2213+ # that are same as this one, and that share the appropriate
2214+ # column number.
2215+ # Add to a list associated with each axes of sibblings.
2216+ # This list is inspected in `axis.draw` by
2217+ # `axis._update_label_position`.
2218+ for axc in axs :
2219+ if axc != ax :
2220+ if axc .yaxis .get_label_position () == labpo :
2221+ ss = axc .get_subplotspec ()
2222+ nrows , ncols , row0 , row1 , colc0 , colc1 = \
2223+ ss .get_rows_columns ()
2224+ if (labpo == 'left' and colc0 == col0 or
2225+ labpo == 'right' and colc1 == col1 ):
2226+ # grouper for groups of ylabels to align
2227+ self ._align_ylabel_grp .join (ax , axc )
2228+
2229+ def align_labels (self , axs = None ):
2230+ """
2231+ Align the xlabels and ylabels of subplots with the same subplots
2232+ row or column (respectively) if label alignment is being
2233+ done automatically (i.e. the label position is not manually set).
2234+
2235+ Alignment persists for draw events after this is called.
2236+
2237+ Parameters
2238+ ----------
2239+ axs : list of `~matplotlib.axes.Axes` (None)
2240+ Optional list (or ndarray) of `~matplotlib.axes.Axes` to
2241+ align the labels. Default is to align all axes on the figure.
2242+
2243+ See Also
2244+ --------
2245+ matplotlib.figure.Figure.align_xlabels
2246+
2247+ matplotlib.figure.Figure.align_ylabels
2248+ """
2249+ self .align_xlabels (axs = axs )
2250+ self .align_ylabels (axs = axs )
2251+
20872252
20882253def figaspect (arg ):
20892254 """
0 commit comments