2013-10-09 5 views
16

아래 그림에서는 숫자 스케일이 다른 두 개의 산점도가 있으므로 Y 축 레이블이 정렬되지 않습니다. y 축 레이블에 수평 정렬을 적용 할 수있는 방법이 있습니까?matplotlib : 누적 분산 형 플롯에서 y 축 레이블 맞추기

import matplotlib.pylab as plt 
import random 
import matplotlib.gridspec as gridspec 

random.seed(20) 
data1 = [random.random() for i in range(10)] 
data2 = [random.random()*1000 for i in range(10)] 

gs = gridspec.GridSpec(2,1) 
fig = plt.figure() 

ax = fig.add_subplot(gs[0]) 
ax.plot(data1) 
ax.set_ylabel(r'Label One', size =16) 

ax = fig.add_subplot(gs[1]) 
ax.plot(data2) 
ax.set_ylabel(r'Label Two', size =16) 

plt.show() 

stacked scatter plots

+0

여기에 설명 된 내용은 http://matplotlib.org/faq/howto_faq입니다.html # align-my-ylabels-across-multiple-subplots –

답변

18

당신은 set_label_coords 방법을 사용할 수 있습니다. 당신이 described hereset_label_coords()를 사용하여 해결을 위해 무엇을 찾고있는 코멘트에 게시 된

import matplotlib.pylab as plt 
import random 
import matplotlib.gridspec as gridspec 

random.seed(20) 
data1 = [random.random() for i in range(10)] 
data2 = [random.random()*1000 for i in range(10)] 

gs = gridspec.GridSpec(2,1) 
fig = plt.figure() 

ax = fig.add_subplot(gs[0]) 
ax.plot(data1) 
ax.set_ylabel(r'Label One', size =16) 
ax.get_yaxis().set_label_coords(-0.1,0.5) 

ax = fig.add_subplot(gs[1]) 
ax.plot(data2) 
ax.set_ylabel(r'Label Two', size =16) 
ax.get_yaxis().set_label_coords(-0.1,0.5) 

enter image description here

+0

감사합니다. "ax.get_yaxis(). get_label(). set_ha ('left')"행을 따라 무언가를하려했지만 작동하지 않았습니다. 라벨 정렬이 어떻게 작동하는지 완전히 이해하지 못했을 것 같습니다. – dimka

+3

두 축의 눈금 레이블에서 허용되는 최소 거리를 자동으로 결정하는 방법이 있습니까? 나는. 독립적 인 자동 위치가 무엇인지 알아 내고, 명시 적으로 모두를 가장 큰 것과 동일하게 설정하십시오. – andybuckley

+3

@andybuckley, 방금 라벨을 자동으로 정렬하여 놀았습니다. 'ax.yaxis.label.get_position()'을 사용하여 위치의 최소/최대 값을 얻을 수는 있지만 좌표 공간은'ax.yaxis.set_label_coords()'에서 사용 된 것과 같지 않습니다. 'ax.yaxis.label.set_position()'과 약간의 해킹 :'ax.yaxis._autolabelpos = False'를 사용하거나'draw()'를 호출 할 때 위치를 재설정합니다. –

2

. 여기

labelx = -0.5 

ax = fig.add_subplot(gs[0]) 
ax.plot(data1) 
ax.set_ylabel(r'Label One', size=16) 
ax.yaxis.set_label_coords(labelx, 0.5) 

ax = fig.add_subplot(gs[1]) 
ax.plot(data2) 
ax.set_ylabel(r'Label Two', size=16) 
ax.yaxis.set_label_coords(labelx, 0.5) 
1

나는 자동으로 라벨을 정렬 위해 작성한 함수이지만, 대화 형, 스크립트에서 작동하지 않는 것 : 귀하의 경우를 들어이 같은 일이 될 것입니다.

def align_labels(axes_list,axis='y',align=None): 
    if align is None: 
     align = 'l' if axis == 'y' else 'b' 
    yx,xy = [],[] 
    for ax in axes_list: 
     yx.append(ax.yaxis.label.get_position()[0]) 
     xy.append(ax.xaxis.label.get_position()[1]) 

    if axis == 'x': 
     if align in ('t','top'): 
      lim = max(xy) 
     elif align in ('b','bottom'): 
      lim = min(xy) 
    else: 
     if align in ('l','left'): 
      lim = min(yx) 
     elif align in ('r','right'): 
      lim = max(yx) 

    if align in ('t','b','top','bottom'): 
     for ax in axes_list: 
      t = ax.xaxis.label.get_transform() 
      x,y = ax.xaxis.label.get_position() 
      ax.xaxis.set_label_coords(x,lim,t) 
    else: 
     for ax in axes_list: 
      t = ax.yaxis.label.get_transform() 
      x,y = ax.yaxis.label.get_position() 
      ax.yaxis.set_label_coords(lim,y,t) 

그리고 예 :

fig,ax = subplots(2,2) 
ax00,ax01 = ax[0] 
ax10,ax11 = ax[1] 
ax00.set_ylim(1000,5000) 
ax00.set_ylabel('top') 
ax10.set_ylabel('bottom') 
ax10.set_xlabel('left') 
ax11.set_xlabel('right') 
ax11.xaxis.axis_date() 
fig.autofmt_xdate() 
#we have to call draw() so that matplotlib will figure out the automatic positions 
fig.canvas.draw() 
align_labels(ax[:,0],'y') 
align_labels(ax[1],'x') 

example figure

0

나는 끝에 솔루션을 제공하지만, 처음 엔 성공으로 이어질하지 않는 방법을 말한다.

최근에이 문제를 다시 살펴 보았습니다. 다양한 솔루션을 시도했습니다. 즉, 서로 다른 좌표계 간의 가능한 모든 변환 조합을 시도하고 tight_layout()과의 관계를 시도했습니다. 나는 backend_pdf으로 실험 했으므로 대화 형 미디어에 관해서는 설명 할 수 없습니다. 그러나 간단히 말해서, 내 결론은 위치를 찾아서 변형 시키려고해도 축 레이블을 정렬하는 것이이 레벨에서 불가능하다는 것입니다. 아마 어떻게 든 가능해야합니다. 예를 들어 어떻게 든 내부적으로 matplotlib은 서브 플롯 자체의 축을 정렬 할 수 있습니다. 만 두 번 pdf 파일로 그리기 및 inbetween 아래 같은 일을 함께, 더 나은 위치를 달성하지만, 여전히 정렬되지 수 :

# sorry for the `self`, this is from a class 
def align_x_labels(self): 
    self.lowest_ax = min(self.axes.values(), 
         key = lambda ax: ax.xaxis.label.get_position()[1]) 
    self.lowest_xlab_dcoo = self.lowest_ax.transData.transform(
     self.lowest_ax.xaxis.label.get_position()) 
    list(
     map(
       lambda ax: \ 
        ax.xaxis.set_label_coords(
         self.fig.transFigure.inverted().transform(
          ax.transAxes.transform((0.5, 0.5)))[0], 
         self.fig.transFigure.inverted().transform(
          self.lowest_xlab_dcoo)[1], 
         transform = self.fig.transFigure 
        ), 
       self.axes.values() 
      ) 
    ) 

그것은 기본적인 기능을 달성 할 수없는 이러한 수치이며, 그것은이다 다른 좌표 공간이 어떻게 변형되고 플롯팅의 다른 단계에서 재조정되는지를 모호하게 만듭니다. matplotlib webpage은 아키텍처 개요를 제시하고 간단한 사례를 제시하지만 이와 같은 상황을 설명하지 못하기 때문에 이에 대한 명확한 설명을 읽어 주셔서 감사드립니다. 또한 좌표를 수락하거나 반환하는 메소드가 좌표를 docstring에 알려주지 않는다는 사실에 놀랐습니다. 마지막으로 매우 유용한 것으로 발견되었습니다 this tutorial. 끝에 해결

는 대신 변환 장난에, I 제로 높이 투명 축 (같은 추가적인 행이 Y 축 라벨 제로 폭 컬럼 할 수 GridSpec에서 만든). 그런 다음 verticalalignmenttop으로 설정하여이 하위 플롯의 라벨을 추가했습니다.

# get one of the zero height phantom subplots to `self.ax`: 
self.get_subplot(i, 1) 
# set empty ticklabels: 
self.ax.xaxis.set_ticklabels([]) 
self.ax.yaxis.set_ticklabels([]) 
# set the axis label: 
self.ax.set_xlabel(labtext, fontproperties = self.fp_axis_lab) 
# and this is matter of aesthetics 
# sometimes bottom or center might look better: 
self.ax.xaxis.label.set_verticalalignment('top') 
관련 문제