How to add a second x-axis in matplotlib

匿名 (未验证) 提交于 2019-12-03 01:40:02

问题:

I have a very simple question. I need to have a second x-axis on my plot and I want that this axis has a certain number of tics that correspond to certain position of the first axis.

Let's try with an example. Here I am plotting the dark matter mass as a function of the expansion factor, defined as 1/(1+z), that 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, on the top of my plot, showing the corresponding z for some values of the expansion factor. Is that possible? If yes, how can I have xtics ax

回答1:

I'm taking a cue from the comments in @Dhara's answer, it sounds like you want to set a list of new_tick_locations by a function from the old x-axis to the new x-axis. The tick_function below takes in a numpy array of points, 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() 



回答2:

You can use twiny to create 2 x-axis scales. 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() 

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

Output:



回答3:

Answering your question in Dhara's answer comments: "I would like on the second x-axis these tics: (7,8,99) corresponding to the x-axis position 10, 30, 40. Is that 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:



回答4:

If You want Your upper axis to be a function of the lower axis tick-values:

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:



回答5:

I'm forced to post this as an answer instead of a comment due to low reputation. I had a similar problem to Matteo. The difference being that I had no 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 the 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 in use also cleared my plot from ax1.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!