2012-05-09 3 views
49

У меня очень простой вопрос. Мне нужно иметь вторую ось x на моем графике, и я хочу, чтобы эта ось имела определенное количество тиков, которые соответствуют определенному положению первой оси.Как добавить вторую ось x в matplotlib

Давайте попробуем на примере. Здесь я откладывая массу темной материи в зависимости от коэффициента расширения, который определяется как 1/(1 + Z), который колеблется от 0 до 1.

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

Я хотел бы иметь другую ось х, в верхней части моего графика, показывая соответствующий z для некоторых значений коэффициента расширения. Это возможно? Если да, то как я могу получить xtics ax

+0

Какую графическую библиотеку вы используете? – sth

+0

Функции, которые вы используете, не встроены в python - я предполагаю, что вы говорите о [matplotlib] (http://matplotlib.sourceforge.net/)? Если это так, вопрос [Как построить несколько осей x или y в matplotlib?] (Http: // stackoverflow.com/questions/3918028/how-do-i-plot-multiple-x-or-y-axes-in-matplotlib), похоже, охватывает это. – James

+0

Я отредактировал заголовок, да, я использую matplotlib. – Brian

ответ

68

Я беру пример с комментариями в @ ответ DHARA, это звучит, как вы хотите, чтобы установить список new_tick_locations функцией от старой оси х до новой оси х. 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() 

enter image description here

+0

именно то, что мне нужно – eusoubrasileiro

+1

Если вы хотите добавить заголовок, обратитесь к этому вопросу: http://stackoverflow.com/questions/12750355/python-matplotlib-figure-title-overlaps-axes-label-when-using- twiny – szmoore

+0

@ Заработано, любая идея, если это возможно с одной из шкал в шкале журнала? – tiago

12

Вы можете использовать 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() 

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

Выход: enter image description here

+0

Прошу прощения, но это не то, что я просил. Мне не нужно отображать функции на одном и том же участке с другой осью. Мне просто нужно иметь вторую ось x, в верхней части моего сюжета, пометить в соответствии с некоторым специальным положением на первой оси x. – Brian

+0

Затем просто добавьте манекенную 2-ю осью с нужным вам диапазоном и очистите его. См. Мой отредактированный ответ – Dhara

+0

Извините, но ваш код не работает. Я скопировал и вставил его, а затем вторую ось x пересекалась с первой. – Brian

7

Отвечая на ваш вопрос в комментариях ответа DHARA в: "Я хотел бы на втором х (7,8,99), соответствующие положению 10, 30, 40 оси x. Возможно ли это каким-то образом? « Да, это так.

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() 

Вы получите: enter image description here

5

Если Вы хотите, чтобы Ваша верхняя ось является функцией нижней оси клещевого значения:

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() 
ax1Xs = ax1.get_xticks() 

ax2Xs = [] 
for X in ax1Xs: 
    ax2Xs.append(X * 2) 

ax2.set_xticks(ax1Xs) 
ax2.set_xbound(ax1.get_xbound()) 
ax2.set_xticklabels(ax2Xs) 

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") 

Дает:

enter image description here

+0

+1 настройка привязки была тем, что я искал – dashesy

0

Я вынужден опубликовать это как Ответ вместо комментария из-за низкой репутации. У меня была аналогичная проблема с Маттео. Разница заключалась в том, что у меня не было карты с моей первой оси x до моей второй оси x, только сами значения x. Поэтому я хотел установить данные на моей второй оси х напрямую, а не на тиках, однако нет axes.set_xdata. Я был в состоянии использовать ответ DHARA, чтобы сделать это с модификацией:

ax2.lines = [] 

вместо использования:

ax2.cla() 

При использовании также очистил свой участок от ax1.

+1

Это был бы лучший ответ, если бы вы предоставили пример кода, а не только изменения из ответа Дхара. – Benjamin

Смежные вопросы