matplotlib에서 두 번째 x 축을 추가하는 방법


78

아주 간단한 질문이 있습니다. 내 플롯에 두 번째 x 축이 있어야하고이 축에 첫 번째 축의 특정 위치에 해당하는 특정 수의 틱이 있어야합니다.

예를 들어 보겠습니다. 여기에서는 0에서 1까지의 범위 인 1 / (1 + z)로 정의 된 확장 계수의 함수로 암흑 물질 질량을 플로팅하고 있습니다.

semilogy(1/(1+z),mass_acc_massive,'-',label='DM')
xlim(0,1)
ylim(1e8,5e12)

내 플롯 상단에 확장 계수의 일부 값에 해당하는 z를 표시하는 또 다른 x 축을 갖고 싶습니다. 가능합니까? 그렇다면 xtics ax를 어떻게 가질 수 있습니까?


사용중인 함수는 파이썬에 내장되어 있지 않습니다. matplotlib 에 대해 이야기하고 있다고 가정합니다 . 그렇다면 matplotlib에서 여러 x 또는 y 축을 어떻게 플로팅합니까? 이것을 덮는 것 같습니다.
James

답변:


116

@Dhara의 답변에있는 주석에서 단서를 new_tick_locations받고 있는데, 이전 x 축에서 새 x 축으로 함수별로 목록을 설정하려는 것처럼 들립니다 . 은 tick_function아래에 새 값을 매핑하고 서식을 점 NumPy와 배열한다 :

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

X = np.linspace(0,1,1000)
Y = np.cos(X*20)

ax1.plot(X,Y)
ax1.set_xlabel(r"Original x-axis: $X$")

new_tick_locations = np.array([.2, .5, .9])

def tick_function(X):
    V = 1/(1+X)
    return ["%.3f" % z for z in V]

ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(new_tick_locations)
ax2.set_xticklabels(tick_function(new_tick_locations))
ax2.set_xlabel(r"Modified x-axis: $1/(1+X)$")
plt.show()

여기에 이미지 설명 입력


2
제목도 추가하려면 다음 질문을 참조하십시오. stackoverflow.com/questions/12750355/…
szmoore

@Hooked, 로그 스케일의 스케일 중 하나로 이것이 가능하다면 어떤 생각이 있습니까?
tiago

2
@tiago 지금은 확인할 수 없지만 ax.set_yscale('log')작동합니까?
Hooked

5
이 예제는 xlim이 0과 1 (기본값) 사이이므로 "우연히"작동합니다. 임의의 한계에 대해이 작업을 수행하려면 두 축의 한계가 ax2.set_xlim(ax1.get_xlim())그렇지 않은 경우 X상단 및 X하단 의 한계와 일치하는지 확인해야합니다 .
mforbes

Matplotlib는 보조 축을 추가하는 기본 방법을 구현했습니다. 여기에 자신의 예를 참조하십시오 matplotlib.org/3.1.0/gallery/subplots_axes_and_figures/...
스테파노

27

twiny를 사용하여 2 개의 x 축 스케일을 생성 할 수 있습니다. 예를 들면 :

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

a = np.cos(2*np.pi*np.linspace(0, 1, 60.))

ax1.plot(range(60), a)
ax2.plot(range(100), np.ones(100)) # Create a dummy plot
ax2.cla()
plt.show()

참고 : http://matplotlib.sourceforge.net/faq/howto_faq.html#multiple-y-axis-scales

산출: 여기에 이미지 설명 입력


미안하지만 그게 내가 요청한 게 아니에요. 다른 축을 가진 동일한 플롯의 함수에 플롯 할 필요가 없습니다. 내 플롯의 맨 위에 첫 번째 x 축의 특정 위치에 해당하는 두 번째 x 축이 있으면됩니다.
Brian

그런 다음 원하는 범위로 더미 두 번째 축을 추가하고 지 웁니다. 내 편집 된 답변보기
Dhara

죄송하지만 코드가 작동하지 않습니다. 복사하여 붙여 넣은 다음 두 번째 x 축이 첫 번째 x 축과 겹칩니다.
Brian

출력을 첨부했는데 이것이 당신이 원하는 것이 아닙니까?
Dhara

별로. 귀하의 예를 참조로 두 번째 x 축에 이러한 틱을 표시합니다 : (7,8,99) x 축 위치 10, 30, 40에 해당합니다. 어떤 식 으로든 가능합니까?
Brian

13

위쪽 축이 아래쪽 축 눈금 값의 함수가되도록하려면 아래와 같이 할 수 있습니다. 참고 : 가끔get_xticks() 가시 범위를 벗어난 틱이있을 수 있으며, 변환시 허용해야합니다.

import matplotlib.pyplot as plt

fig, ax1 = plt.subplots()

ax1 = fig.add_subplot(111)

ax1.plot(range(5), range(5))

ax1.grid(True)

ax2 = ax1.twiny()
ax2.set_xticks(ax1Xs)
ax2.set_xbound(ax1.get_xbound())
ax2.set_xticklabels([x * 2 for x in ax1.get_xticks()])

title = ax1.set_title("Upper x-axis ticks are lower x-axis ticks doubled!")
title.set_y(1.1)
fig.subplots_adjust(top=0.85)

fig.savefig("1.png")

제공 :

여기에 이미지 설명 입력


11

Dhara의 답변 코멘트에서 귀하의 질문에 답하십시오. " 두 번째 x 축에 이러한 틱 (7,8,99)이 x 축 위치 10, 30, 40에 해당합니다. 어떤 식 으로든 가능합니까? "예 , 그것은.

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)

a = np.cos(2*np.pi*np.linspace(0, 1, 60.))
ax1.plot(range(60), a)

ax1.set_xlim(0, 60)
ax1.set_xlabel("x")
ax1.set_ylabel("y")

ax2 = ax1.twiny()
ax2.set_xlabel("x-transformed")
ax2.set_xlim(0, 60)
ax2.set_xticks([10, 30, 40])
ax2.set_xticklabels(['7','8','99'])

plt.show()

당신은 얻을 것이다: 여기에 이미지 설명 입력


4

matplotlib 3.1부터는 다음을 사용할 수 있습니다. ax.secondary_xaxis

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(1,13, num=301)
y = (np.sin(x)+1.01)*3000

# Define function and its inverse
f = lambda x: 1/(1+x)
g = lambda x: 1/x-1

fig, ax = plt.subplots()
ax.semilogy(x, y, label='DM')

ax2 = ax.secondary_xaxis("top", functions=(f,g))

ax2.set_xlabel("1/(x+1)")
ax.set_xlabel("x")
plt.show()


2

평판이 낮기 때문에 댓글 대신 답변으로 게시해야합니다. Matteo와 비슷한 문제가있었습니다. 차이점은 첫 번째 x 축에서 두 번째 x 축까지의 맵이없고 x 값 자체 만 있다는 것입니다. 그래서 틱이 아닌 두 번째 x 축에 데이터를 직접 설정하고 싶었지만 axes.set_xdata. Dhara의 답변을 사용하여 수정하여 수행 할 수있었습니다.

ax2.lines = []

사용하는 대신:

ax2.cla()

사용 중일 때 ax1.


3
Dhara의 답변의 변경 사항 대신 코드 예제를 제공하면 더 나은 답변이 될 것입니다.
벤자민
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.