用于子图的pyplot轴标签
我有以下情节:
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')
我希望能够创build轴标签和标题不仅为每个两个子图,但也常见的标签跨越两个子图。 例如,由于两个图都具有相同的坐标轴,所以我只需要一组x轴和y轴标签。 尽pipe如此,我还是希望为每个子区域创build不同的标题。
我尝试了一些东西,但没有一个能正确运行
您可以创build一个覆盖两个子图的大型子图,然后设置通用标签。
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)
另一种方法是使用fig.text()直接设置通用标签的位置。
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)
一个简单的方法使用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")
廖文伟的答案是好的,如果你不是试图出口vectorgraphics,或者你已经设置你的matplotlib后端忽略无色轴; 否则隐藏轴将显示在导出的graphics中。
我在这里的答案suplabel
类似于使用fig.text
函数的fig.text
。 因此,没有斧头艺术家被创造出来并变得无色。 但是,如果您尝试多次调用,则会将文本添加到对方的顶部(如图fig.suptitle
)。 fig.add_subplot(111)
的答案没有,因为fig.add_subplot(111)
将返回相同的轴对象,如果它已经被创build。
我的函数也可以在绘图创build后调用。
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)
这里是一个解决scheme,您可以设置其中一个绘图的ylabel并调整它的位置,使其垂直居中。 这样你可以避免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)')