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

Reply via email to