python - Control Matplotlib legend box width for wrapping -


i trying fix width of legend box in matplotlib (python 2.7). here simple example of code using:

import numpy np import pylab plt fig = plt.figure(figsize=(8.5, 8.5)) ax = fig.add_axes([0.0882, 0.0588, 0.8882, 0.9118])  x = np.array([0,1,2,33]) y = np.array([0.1,2,4,8]) z = np.array([0,1,3.7,7]) t = np.array([0.5,1,12,41]) v = np.array([0.9,7,24,54]) = np.array([0.2,11,17,61]) q = np.array([0.4,17,15,80]) r = np.array([0.9,3.7,18,44]) s = np.array([0.2,10,19,31])  y1 = y+1 z1 = z+1 t1 = t+1 v1 = v+1 a1 = a+1 q1 = q+1 r1 = r+1 s1 = s+1  ax.plot(x,y,label='y') ax.plot(x,z,label='z') ax.plot(x,t,label='t') ax.plot(x,v,label='v') ax.plot(x,a,label='a') ax.plot(x,y1,label='y1') ax.plot(x,z1,label='z1') ax.plot(x,t1,label='t1') ax.plot(x,v1,label='v1') ax.plot(x,a1,label='a1') ax.plot(x,q1,label='q1') ax.plot(x,r1,label='r1') ax.plot(x,s1,label='s1')  lg = ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05), ncol=10)  fig.savefig('a_test_position.png', facecolor='white', dpi = 300, bbox_inches='tight') 

when keep first 3 ax.plot() statements, this. however, when include ax.plot() statements, output becomes this

problem: need legend box to:

  1. start @ 0 on x-axis
  2. end @ maximum x-value on x-axis (in case, max value 35)
  3. wrap new row after reaches maximum on x-axis

when there small number of entries (eg. first plot), want legend centered. code working correctly this, not need change behavior. however, need change behavior when there many entries legend needs wrap around new row (2nd plot).

how can done in matplotlib? there way specify size of legend box?

a solution iterate on ncol argument until width of legend becomes larger width of axe. then, make legend expand entire width of axe using optimal value found ncol , mode='expand' option. in case entries can fit in single row, "centered layout" kept, without expanding legend width of axe.

below code sample shows how can done:

ncol = 1 lgwidth_old = 0. renderer = fig.canvas.get_renderer() while true:     lg = ax.legend(loc='upper center', bbox_to_anchor=(0., -0.05, 1., 0.),                    borderaxespad=0, ncol=ncol)     fig.canvas.draw()     lgbbox = lg.get_window_extent(renderer).inverse_transformed(ax.transaxes)      if lgwidth_old == lgbbox.width:         # entries fit within single row. keep legend         # , break loop.         break      if lgbbox.width < 1:         # width of legend still smaller of axe.         # continue iterating.         ncol += 1         lgwidth_old = lgbbox.width     else:          # width of legend larger of axe.         # backtrack ncol, plot legend span entire width of         # axe, , break loop.         ncol -= 1         lg = ax.legend(loc='upper center', bbox_to_anchor=(0., -0.05, 1., 0.),                        borderaxespad=0, ncol=ncol, mode='expand')                  break      if ncol > 100:         print('number max of iteration reached. wrong.')         break  

which results in (when added code):

enter image description here


Comments

Popular posts from this blog

dns - How To Use Custom Nameserver On Free Cloudflare? -

python - Pygame screen.blit not working -

c# - Web API response xml language -