tags de ejes pyplot para subttwigs

Tengo la siguiente ttwig:

import matplotlib.pyplot as plt fig2 = plt.figure() ax3 = fig2.add_subplot(2,1,1) ax4 = fig2.add_subplot(2,1,2) ax4.loglog(x1, y1) ax3.loglog(x2, y2) ax3.set_ylabel('hello') 

Quiero poder crear tags de ejes y títulos no solo para cada una de las dos subttwigs, sino también tags comunes que abarquen ambas subttwigs. Por ejemplo, dado que ambos gráficos tienen ejes idénticos, solo necesito un conjunto de tags de ejes xey. Sin embargo, quiero diferentes títulos para cada subttwig.

Intenté algunas cosas, pero ninguna funcionó bien

Puede crear una subplot grande que cubra las dos subttwigs y luego establecer las tags comunes.

 import random import matplotlib.pyplot as plt x = range(1, 101) y1 = [random.randint(1, 100) for _ in xrange(len(x))] y2 = [random.randint(1, 100) for _ in xrange(len(x))] fig = plt.figure() ax = fig.add_subplot(111) # The big subplot ax1 = fig.add_subplot(211) ax2 = fig.add_subplot(212) # Turn off axis lines and ticks of the big subplot ax.spines['top'].set_color('none') ax.spines['bottom'].set_color('none') ax.spines['left'].set_color('none') ax.spines['right'].set_color('none') ax.tick_params(labelcolor='w', top='off', bottom='off', left='off', right='off') ax1.loglog(x, y1) ax2.loglog(x, y2) # Set common labels ax.set_xlabel('common xlabel') ax.set_ylabel('common ylabel') ax1.set_title('ax1 title') ax2.set_title('ax2 title') plt.savefig('common_labels.png', dpi=300) 

common_labels.png

Otra forma es usar fig.text () para establecer las ubicaciones de las tags comunes directamente.

 import random import matplotlib.pyplot as plt x = range(1, 101) y1 = [random.randint(1, 100) for _ in xrange(len(x))] y2 = [random.randint(1, 100) for _ in xrange(len(x))] fig = plt.figure() ax1 = fig.add_subplot(211) ax2 = fig.add_subplot(212) ax1.loglog(x, y1) ax2.loglog(x, y2) # Set common labels fig.text(0.5, 0.04, 'common xlabel', ha='center', va='center') fig.text(0.06, 0.5, 'common ylabel', ha='center', va='center', rotation='vertical') ax1.set_title('ax1 title') ax2.set_title('ax2 title') plt.savefig('common_labels_text.png', dpi=300) 

common_labels_text.png

Una forma simple de usar subplots :

 import matplotlib.pyplot as plt fig, axes = plt.subplots(3, 4, sharex=True, sharey=True) # add a big axes, hide frame fig.add_subplot(111, frameon=False) # hide tick and tick label of the big axes plt.tick_params(labelcolor='none', top='off', bottom='off', left='off', right='off') plt.grid(False) plt.xlabel("common X") plt.ylabel("common Y") 

La respuesta de Wen-wei Liao es buena si no estás tratando de exportar gráficos vectoriales o si has configurado tus backends matplotlib para ignorar los ejes incoloros; de lo contrario, los ejes ocultos aparecerían en el gráfico exportado.

Mi respuesta suplabel aquí es similar al fig.suptitle que usa la función fig.text . Por lo tanto, no hay ningún artista de ejes creado y descolorido. Sin embargo, si intentas llamarlo varias veces, obtendrás texto añadido uno encima del otro (como fig.suptitle también). La respuesta de Wen-wei Liao no, porque fig.add_subplot(111) devolverá el mismo objeto Axes si ya está creado.

Mi función también se puede llamar después de que se hayan creado los diagtwigs.

 def suplabel(axis,label,label_prop=None, labelpad=5, ha='center',va='center'): ''' Add super ylabel or xlabel to the figure Similar to matplotlib.suptitle axis - string: "x" or "y" label - string label_prop - keyword dictionary for Text labelpad - padding from the axis (default: 5) ha - horizontal alignment (default: "center") va - vertical alignment (default: "center") ''' fig = pylab.gcf() xmin = [] ymin = [] for ax in fig.axes: xmin.append(ax.get_position().xmin) ymin.append(ax.get_position().ymin) xmin,ymin = min(xmin),min(ymin) dpi = fig.dpi if axis.lower() == "y": rotation=90. x = xmin-float(labelpad)/dpi y = 0.5 elif axis.lower() == 'x': rotation = 0. x = 0.5 y = ymin - float(labelpad)/dpi else: raise Exception("Unexpected axis: x or y") if label_prop is None: label_prop = dict() pylab.text(x,y,label,rotation=rotation, transform=fig.transFigure, ha=ha,va=va, **label_prop) 

Aquí hay una solución en la que configura la etiqueta de una de las gráficas y ajusta la posición de la misma para que se centre verticalmente. De esta forma evitará los problemas mencionados por KYC.

 import numpy as np import matplotlib.pyplot as plt def set_shared_ylabel(a, ylabel, labelpad = 0.01): """Set ay label shared by multiple axes Parameters ---------- a: list of axes ylabel: string labelpad: float Sets the padding between ticklabels and axis label""" f = a[0].get_figure() f.canvas.draw() #sets f.canvas.renderer needed below # get the center position for all plots top = a[0].get_position().y1 bottom = a[-1].get_position().y0 # get the coordinates of the left side of the tick labels x0 = 1 for at in a: at.set_ylabel('') # just to make sure we don't and up with multiple labels bboxes, _ = at.yaxis.get_ticklabel_extents(f.canvas.renderer) bboxes = bboxes.inverse_transformed(f.transFigure) xt = bboxes.x0 if xt < x0: x0 = xt tick_label_left = x0 # set position of label a[-1].set_ylabel(ylabel) a[-1].yaxis.set_label_coords(tick_label_left - labelpad,(bottom + top)/2, transform=f.transFigure) length = 100 x = np.linspace(0,100, length) y1 = np.random.random(length) * 1000 y2 = np.random.random(length) f,a = plt.subplots(2, sharex=True, gridspec_kw={'hspace':0}) a[0].plot(x, y1) a[1].plot(x, y2) set_shared_ylabel(a, 'shared y label (au)') 

enter image description here

    Intereting Posts