labels - punto - etiquetas de ejes pyplot para subtramas
python graficos 2d (4)
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 a y 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 (a. u.)'')
Tengo la siguiente trama:
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 etiquetas de ejes y títulos no solo para cada una de las dos subtramas, sino también etiquetas comunes que abarquen ambas subtramas. Por ejemplo, dado que ambos gráficos tienen ejes idénticos, solo necesito un conjunto de etiquetas de ejes xey. Sin embargo, quiero diferentes títulos para cada subtrama.
Intenté algunas cosas, pero ninguna funcionó bien
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 diagramas.
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)
Puede crear una subparcela grande que cubra las dos subtramas y luego establecer las etiquetas 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)
Otra forma es usar fig.text () para establecer las ubicaciones de las etiquetas 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)
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")