Here is a slightly revised version of your script. It has a separate axes for labeling whose width is determined by the maximum width of the labels (using MaxExtent from axes_grid toolkit). Give it a try and see if it fits your needs.
Regards, -JJ import numpy as np import matplotlib.pyplot as plt from scipy.stats import gamma from mpl_toolkits.axes_grid import make_axes_locatable fig = plt.figure(1, (10, 10)) ax1 = fig.add_subplot(1, 1, 1) labels = ('0-9', '10-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-79', '80-89', '90-99') pad = np.max([len(i) for i in labels]) * .15 divider = make_axes_locatable(ax1) from mpl_toolkits.axes_grid.axes_size import MaxExtent labeltexts = [] labelextent = MaxExtent(labeltexts, "width") padsmall=0.1 label_axes = divider.new_horizontal(size=labelextent, pad=padsmall, sharey=ax1, frame_on=False) label_axes.xaxis.set_visible(False) label_axes.yaxis.set_visible(False) fig.add_axes(label_axes) ax2 = divider.new_horizontal(size="100%", pad=padsmall, sharey=ax1) fig.add_axes(ax2) N = 10 ind = np.arange(N) # the x locations for the groups width = 0.35 # the width of the bars x = [gamma.pdf(i, 1, scale=2) for i in range(N)] y = [gamma.pdf(i, 5, scale=1) for i in range(N)] ind = np.arange(N) ax1.barh(ind, x, align="center") ax2.barh(ind, y, align="center") for loc, spine in ax1.spines.iteritems(): if loc in ['left','top']: spine.set_color('none') # don't draw spine for loc, spine in ax2.spines.iteritems(): if loc in ['right','top']: spine.set_color('none') # don't draw spine ax1.set_title('Men') ax2.set_title('Women') ax1.set_ylim(-0.5, N-0.5) #ax2.set_ylim(0, N) # Name bars ax1.set_yticks(ind) ax1.xaxis.set_ticks_position('bottom') ax2.xaxis.set_ticks_position('bottom') ax1.yaxis.set_ticks_position('right') ax2.yaxis.set_ticks_position('left') for tl in ax1.get_yticklabels()+ax2.get_yticklabels(): tl.set_visible(False) for i, l in zip(ind, labels): l = label_axes.annotate("$%s$"%l, (0.5, i), ha="center", va="center") labeltexts.append(l) ax1.set_xlim(0.5, 0) ax2.set_xlim(0, 0.5) plt.show() On Sun, Jan 31, 2010 at 7:40 PM, Renato Alves <rjal...@igc.gulbenkian.pt> wrote: > Hi everyone > > I've been going around matplotlib objects trying to find a way to > pre-calculate positions depending on input. > > I'm trying to create a function that draws two barplots facing opposite > directions. > > This is what I managed so far: > > ### > > import numpy as np > import matplotlib.pyplot as plt > from scipy.stats import gamma > from mpl_toolkits.axes_grid import make_axes_locatable > > fig = plt.figure(1, (10, 10)) > ax1 = fig.add_subplot(1, 1, 1) > > ax1.set_xlim(1,0) > > labels = ('0-9', '10-19', '20-29', '30-39', '40-49', > '50-59', '60-69', '70-79', '80-89', '90-99') > > pad = np.max([len(i) for i in labels]) * .15 > > divider = make_axes_locatable(ax1) > ax2 = divider.new_horizontal(size="100%", pad=pad, sharey=ax1) > fig.add_axes(ax2) > > N = 10 > ind = np.arange(N) # the x locations for the groups > width = 0.35 # the width of the bars > > x = [gamma.pdf(i, 1, scale=2) for i in range(N)] > y = [gamma.pdf(i, 5, scale=1) for i in range(N)] > > ind = np.arange(N) > > ax1.barh(ind, x) > ax2.barh(ind, y) > > for loc, spine in ax1.spines.iteritems(): > if loc in ['left','top']: > spine.set_color('none') # don't draw spine > > for loc, spine in ax2.spines.iteritems(): > if loc in ['right','top']: > spine.set_color('none') # don't draw spine > > ax1.set_title('Men') > ax2.set_title('Women') > > ax1.set_ylim(0, N) > ax2.set_ylim(0, N) > > # Name bars > ax1.set_yticks(ind + width) > ax1.xaxis.set_ticks_position('bottom') > ax2.xaxis.set_ticks_position('bottom') > ax1.yaxis.set_ticks_position('right') > ax2.yaxis.set_ticks_position('left') > > for tl in ax1.get_yticklabels(): > tl.set_visible(False) > > ax2.set_yticklabels(labels, > horizontalalignment='center' > ) > > for i in ax2.get_yticklabels(): > i.set_position((-(pad * .12) , 0)) > > plt.show() > > ### > > However I would like to generalize this function but he space between > the two plots and the position of the labels is giving me a hard time. > > In particular, the lines: > > pad = np.max([len(i) for i in labels]) * .15 > i.set_position((-(pad * .12) , 0)) > > include two values (.15 and .12) that are completely arbitrary and > defined by trial and error for current labels. > > However with different labels: > labels = ('0000-9000', '10-19', '20-29', '30-39', '40-49', > '50-59', '60-69', '70-79', '80-89', '90000-99000') > > the values are no longer valid and the final image is no longer properly > aligned. > > I know my current approach is not the proper way but due to the > complexity of matplotlib, my very superficial knowledge about it and the > overwhelming documentation this was the closest I could get. > > In the end I would like to contribute the final result as something to > be included in the gallery/examples section of the website as I'm > positive that it will be helpful to others. > > Any comment or suggestion is extremely welcome. > > Cheers, > Renato > > ------------------------------------------------------------------------------ > The Planet: dedicated and managed hosting, cloud storage, colocation > Stay online with enterprise data centers and the best network in the business > Choose flexible plans and management services without long-term contracts > Personal 24x7 support from experience hosting pros just a phone call away. > http://p.sf.net/sfu/theplanet-com > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > ------------------------------------------------------------------------------ The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users