[英]In matplotlib, how to use a secondary axis that is input to the function together with the primary axis?
I have a function with two arguments ( x1
, x2
).我有一个 function 和两个 arguments (
x1
, x2
)。 I would like to plot the function with its result on the y axis, x1
on the x axis and x2
on the right y axis (secondary axis).我想 plot function 的结果在 y 轴上,
x1
在 x 轴上, x2
在右 y 轴(次轴)上。
My problem is that the values of the x1
and x2
axes do not correspond together to the function point.我的问题是
x1
和x2
轴的值不对应于 function 点。
For example:例如:
I want the value read on the primary y axis to match the x1
and x2
inputs of the other two axes.我希望在主 y 轴上读取的值与其他两个轴的
x1
和x2
输入相匹配。
Code:代码:
x1 = np.linspace(0, 10, 10)
x2 = np.linspace(0, 5, 10)
f = lambda x1, x2: np.exp(-x1) / 10 + np.exp(-x2) / 10
resp = []
for i, j in zip(x1, x2):
resp.append(f(i, j))
resp = np.array(resp)
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(x1, resp)
ax1.set_xlabel('(x1)')
ax1.grid(True)
ax1.set_ylabel('(y)')
ax2.set_ylabel('(x2)')
ax2.set_yticks(x2)
plt.xticks(np.arange(min(x1), max(x1)))
plt.show()
If your input arguments are in lockstep, you do not have a function of two arguments.如果您的输入 arguments 处于同步状态,则您没有两个 arguments 的 function。 A function of two arguments has two independent inputs.
两个 arguments 的一个 function 有两个独立的输入。 Your inputs are dependent, so rather than writing
f(x1, x2)
, you have f(x, g(x))
, which is just f'(x)
.你的输入是依赖的,所以你有
f(x, g(x))
,而不是写f(x1, x2)
,这只是f'(x)
。 In the specific example that you have x1 = np.linspace(0, 10, 10)
.在您拥有
x1 = np.linspace(0, 10, 10)
的具体示例中。 Rather than writing x2 = np.linspace(0, 5, 10)
, you can just write x2 = 0.5 * x1
.而不是写
x2 = np.linspace(0, 5, 10)
,你可以写x2 = 0.5 * x1
。 The exponential you have can be written as你拥有的指数可以写成
x = np.linspace(0, 10, 10)
y = np.exp(-x) / 10 + np.exp(-x / 2) / 10
Notice that you do not need a function definition or a loop to compute the y
values.请注意,您不需要 function 定义或循环来计算
y
值。 Using a loop defeats the entire purpose of using numpy.使用循环破坏了使用 numpy 的全部目的。 Your original five lines could have been reduced to
y = np.exp(-x1) / 10 + np.exp(-x2) / 10
in the same way.你原来的五行可以以同样的方式减少到
y = np.exp(-x1) / 10 + np.exp(-x2) / 10
。
Now if you want to see the secondary x
values in the plot of y
vs x
, you can take a page out of the tutorials and do something like:现在,如果您想查看
y
vs x
的 plot 中的辅助x
值,您可以从教程中取出一页并执行以下操作:
fig, ax1 = plt.subplots()
ax1.plot(x, y)
ax1.set_xlabel('(x1)')
ax1.grid(True)
ax1.set_ylabel('(y)')
ax2 = ax1.secondary_xaxis('top', functions=(lambda x: x / 2, lambda x: 2 * x))
ax2.set_xlabel('(x2)')
plt.show()
The result shows "both" inputs in lockstep:结果以锁步显示“两个”输入:
Now if you really did want to have a function of two variables, then any combination of the inputs would produce a valid y
value.现在,如果您确实想要一个包含两个变量的 function,那么输入的任何组合都会产生一个有效的
y
值。 In this case, you would have to use a feature of numpy called broadcasting , which matches array dimensions by lining them up on the right.在这种情况下,您将不得不使用 numpy 的一项称为 广播的功能,该功能通过将数组尺寸排列在右侧来匹配数组尺寸。
Let's say you defined one of the inputs as a transpose:假设您将其中一个输入定义为转置:
x1 = np.linspace(0, 10, 10) # Shape (10,)
x2 = np.linspace(0, 5, 10).reshape(-1, 1) # Shape (10, 1)
The result of an operation on these values will be a (10, 10)
2D array.对这些值进行操作的结果将是一个
(10, 10)
二维数组。 Now you can meaningfully compute y
as function of two independent variables:现在您可以有意义地将
y
计算为两个自变量的 function:
y = np.exp(-x1) / 10 + np.exp(-x2) / 10
To plot such an array, you will need two x-axes and a y-axis, in other words a 3D plot.对于 plot 这样的阵列,您将需要两个 x 轴和一个 y 轴,即 3D plot。 Here is one way to display something like that in matplotlib:
这是在 matplotlib 中显示类似内容的一种方法:
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
fig, ax = plt.subplots(subplot_kw={'projection': '3d'})
s = ax.plot_surface(x1, x2, y, cm=cm.jet)
ax.set_xlabel('(x1)')
ax.set_ylabel('(x2)')
ax.set_zlabel('(y)')
fig.colorbar(s)
Here is the resulting plot:这是生成的 plot:
It is up to you which representation of a function you want.您需要哪种 function 表示由您决定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.