How to add second x axis to matplotlib

I have a very simple question. I need to have a second x axis on my chart, and I want this axis to have a certain number of ticks that correspond to a specific position of the first axis.

Try an example. Here I draw the mass of dark matter as a function of the expansion coefficient, defined as 1 / (1 + z), which ranges from 0 to 1.

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

I would like to have another x axis at the top of my graph, showing the corresponding z for some values ​​of the expansion coefficient. Is it possible? If so, how can I get xtics ax

+52
python matplotlib
May 9 '12 at 10:32
source share
5 answers

I am taking a cue from the comments in @Dhara's answer, it looks like you want to set the list new_tick_locations with a function from the old x axis to the new x axis. tick_function below takes several points of the array, maps them to a new value and formats them:

 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

+72
May 09 '12 at 13:49
source share

You can use twiny to create 2 scales on the x axis. For example:

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

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

Output: enter image description here

+12
May 9 '12 at 11:24
source share

Answering your question in the answers with the answers of Dhar: "I would like these ticks on the second x-axis: (7,8,99) corresponding to the x-axis position 10, 30, 40. Is this possible in some way?" Yes it is.

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

You'll get: enter image description here

+7
May 09 '12 at 2:07 pm
source share

If you want your upper axis to be a function of the galaxies of the lower axis:

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

gives:

enter image description here

+5
May 23 '14 at 14:44
source share

I am forced to post this as an answer instead of a comment due to low reputation. I had a similar problem with Matteo. The difference was that I did not have a map from my first x axis to my second x axis, only the x values ​​themselves. So I wanted to set the data on my second x axis directly, not on ticks, however there is no axes.set_xdata . I was able to use Dhara's answer to do this with a modification:

 ax2.lines = [] 

instead of using:

 ax2.cla() 

When used, my graph also clears from ax1 .

0
Jan 28 '15 at 2:32
source share



All Articles