From: <jd...@us...> - 2008-06-19 17:24:25
|
Revision: 5597 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=5597&view=rev Author: jdh2358 Date: 2008-06-19 10:23:34 -0700 (Thu, 19 Jun 2008) Log Message: ----------- added support for custom positioning of axis labels Modified Paths: -------------- trunk/matplotlib/doc/faq/howto_faq.rst trunk/matplotlib/lib/matplotlib/axis.py Added Paths: ----------- trunk/matplotlib/doc/pyplots/align_ylabels.py Modified: trunk/matplotlib/doc/faq/howto_faq.rst =================================================================== --- trunk/matplotlib/doc/faq/howto_faq.rst 2008-06-19 16:54:54 UTC (rev 5596) +++ trunk/matplotlib/doc/faq/howto_faq.rst 2008-06-19 17:23:34 UTC (rev 5597) @@ -113,6 +113,24 @@ ``markersize``. For more information on configuring ticks, see :ref:`axis-container` and :ref:`tick-container`. + +.. _howto-align-label: + +How do I align my ylabels across multiple subplots? +=================================================== + +If you have multiple subplots over one another, and the y data have +different scales, you can often get ylabels that do not align +vertically across the multiple subplots, which can be unattractive. +By default, matplotlib positions the x location of the ylabel so that +it does not overlap any of the y ticks. You can override this default +behavior by specifying the coordinates of the label. The example +below shows the default behavior in the left subplots, and the manual +setting in the right subplots. + +.. plot:: align_ylabels.py + :include-source: + .. _howto-webapp: How do I use matplotlib in a web application server? Added: trunk/matplotlib/doc/pyplots/align_ylabels.py =================================================================== --- trunk/matplotlib/doc/pyplots/align_ylabels.py (rev 0) +++ trunk/matplotlib/doc/pyplots/align_ylabels.py 2008-06-19 17:23:34 UTC (rev 5597) @@ -0,0 +1,35 @@ +import numpy as np +import matplotlib.pyplot as plt + +box = dict(facecolor='yellow', pad=5, alpha=0.2) + +fig = plt.figure() +fig.subplots_adjust(left=0.2, wspace=0.6) + + +ax1 = fig.add_subplot(221) +ax1.plot(2000*np.random.rand(10)) +ax1.set_title('ylabels not aligned') +ax1.set_ylabel('misaligned 1', bbox=box) +ax1.set_ylim(0, 2000) +ax3 = fig.add_subplot(223) +ax3.set_ylabel('misaligned 2',bbox=box) +ax3.plot(np.random.rand(10)) + + +labelx = -0.3 # axes coords + +ax2 = fig.add_subplot(222) +ax2.set_title('ylabels aligned') +ax2.plot(2000*np.random.rand(10)) +ax2.set_ylabel('aligned 1', bbox=box) +ax2.yaxis.set_label_coords(labelx, 0.5) +ax2.set_ylim(0, 2000) + +ax4 = fig.add_subplot(224) +ax4.plot(np.random.rand(10)) +ax4.set_ylabel('aligned 2', bbox=box) +ax4.yaxis.set_label_coords(labelx, 0.5) + + +plt.show() Modified: trunk/matplotlib/lib/matplotlib/axis.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axis.py 2008-06-19 16:54:54 UTC (rev 5596) +++ trunk/matplotlib/lib/matplotlib/axis.py 2008-06-19 17:23:34 UTC (rev 5597) @@ -503,9 +503,9 @@ """ Public attributes - transData - transform data coords to display coords - transAxis - transform axis coords to display coords + * transData - transform data coords to display coords + * transAxis - transform axis coords to display coords """ LABELPAD = 5 @@ -533,6 +533,7 @@ #self.major = dummy() #self.minor = dummy() + self._autolabelpos = True self.label = self._get_label() self.offsetText = self._get_offset_text() self.majorTicks = [] @@ -542,6 +543,29 @@ self.cla() self.set_scale('linear') + + def set_label_coords(self, x, y, transform=None): + """ + Set the coordinates of the label. By default, the x + coordinate of the y label is determined by the tick label + bounding boxes, but this can lead to poor alignment of + multiple ylabels if there are multiple axes. Ditto for the y + coodinate of the x label. + + You can also specify the coordinate system of the label with + the transform. If None, the default coordinate system will be + the axes coordinate system (0,0) is (left,bottom), (0.5, 0.5) + is middle, etc + + """ + + self._autolabelpos = False + if transform is None: + transform = self.axes.transAxes + + self.label.set_transform(transform) + self.label.set_position((x, y)) + def get_transform(self): return self._scale.get_transform() @@ -703,7 +727,9 @@ # just the tick labels that actually overlap note we need a # *copy* of the axis label box because we don't wan't to scale # the actual bbox + self._update_label_position(ticklabelBoxes, ticklabelBoxes2) + self.label.draw(renderer) self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2) @@ -1139,8 +1165,9 @@ verticalalignment='top', horizontalalignment='center', ) + label.set_transform( mtransforms.blended_transform_factory( - self.axes.transAxes, mtransforms.IdentityTransform() )) + self.axes.transAxes, mtransforms.IdentityTransform() )) self._set_artist_props(label) self.label_position='bottom' @@ -1184,7 +1211,7 @@ Update the label position based on the sequence of bounding boxes of all the ticklabels """ - + if not self._autolabelpos: return x,y = self.label.get_position() if self.label_position == 'bottom': if not len(bboxes): @@ -1374,7 +1401,7 @@ rotation='vertical', ) label.set_transform( mtransforms.blended_transform_factory( - mtransforms.IdentityTransform(), self.axes.transAxes) ) + mtransforms.IdentityTransform(), self.axes.transAxes) ) self._set_artist_props(label) self.label_position='left' @@ -1418,7 +1445,7 @@ Update the label position based on the sequence of bounding boxes of all the ticklabels """ - + if not self._autolabelpos: return x,y = self.label.get_position() if self.label_position == 'left': if not len(bboxes): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |