Python 如何在图形中间绘制轴?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31556446/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to draw axis in the middle of the figure?
提问by Shan
I want to draw a figure in matplotib where the axis are displayed within the plot itself not on the side
我想在 matplotib 中绘制一个图形,其中轴显示在绘图本身而不是侧面
I have tried the following code from here:
我从这里尝试了以下代码:
import math
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
a = []
for item in x:
a.append(1/(1+math.exp(-item)))
return a
x = np.arange(-10., 10., 0.2)
sig = sigmoid(x)
plt.plot(x,sig)
plt.show()
The above code displays the figure like this:
What I would like to draw is something as follows (imagefrom Wikipedia)
我想画的东西如下(图片来自维基百科)
This questiondescribes a similar problem, but it draws a reference line in the middle but no axis.
这个问题描述了一个类似的问题,但它在中间绘制了一条参考线但没有轴。
采纳答案by Jblasco
One way to do it is using spines:
一种方法是使用脊椎:
import math
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
a = []
for item in x:
a.append(1/(1+math.exp(-item)))
return a
x = np.arange(-10., 10., 0.2)
sig = sigmoid(x)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
# Move left y-axis and bottim x-axis to centre, passing through (0,0)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
# Eliminate upper and right axes
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
# Show ticks in the left and lower axes only
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.plot(x,sig)
plt.show()
shows:
显示:
回答by Karl der Kaefer
Basically, I want to comment on the accepted answer (but my rep doesn't allow that). The use of
基本上,我想对接受的答案发表评论(但我的代表不允许)。指某东西的用途
ax.spines['bottom'].set_position('center')
draws the x-axes such that it intersect the y-axes in its center. In case of asymmetric ylim this means that x-axis passes NOT through y=0. Jblasco's answer has this drawback, the intersect is at y=0.5 (the center between ymin=0.0 and ymax=1.0) However, the reference plot of the original question has axes that intersect each other at 0.0 (which is somehow conventional or at least common). To achieve this behaviour,
绘制 x 轴,使其在其中心与 y 轴相交。在不对称 ylim 的情况下,这意味着 x 轴不通过 y=0。Jblasco 的答案有这个缺点,相交在 y=0.5(ymin=0.0 和 ymax=1.0 之间的中心)但是,原始问题的参考图的轴在 0.0 处彼此相交(这在某种程度上是传统的或至少常见的)。为了实现这种行为,
ax.spines['bottom'].set_position('zero')
has to be used. See the following example, where 'zero' makes the axes intersect at 0.0 despite asymmetrically ranges in both x and y.
必须使用。请参见以下示例,其中“零”使轴在 0.0 处相交,尽管 x 和 y 的范围不对称。
import numpy as np
import matplotlib.pyplot as plt
#data generation
x = np.arange(-10,20,0.2)
y = 1.0/(1.0+np.exp(-x)) # nunpy does the calculation elementwise for you
fig, [ax0, ax1] = plt.subplots(ncols=2, figsize=(8,4))
# Eliminate upper and right axes
ax0.spines['top'].set_visible(False)
ax0.spines['right'].set_visible(False)
# Show ticks on the left and lower axes only
ax0.xaxis.set_tick_params(bottom='on', top='off')
ax0.yaxis.set_tick_params(left='on', right='off')
# Move remaining spines to the center
ax0.set_title('center')
ax0.spines['bottom'].set_position('center') # spine for xaxis
# - will pass through the center of the y-values (which is 0)
ax0.spines['left'].set_position('center') # spine for yaxis
# - will pass through the center of the x-values (which is 5)
ax0.plot(x,y)
# Eliminate upper and right axes
ax1.spines['top'].set_visible(False)
ax1.spines['right'].set_visible(False)
# Show ticks on the left and lower axes only (and let them protrude in both directions)
ax1.xaxis.set_tick_params(bottom='on', top='off', direction='inout')
ax1.yaxis.set_tick_params(left='on', right='off', direction='inout')
# Make spines pass through zero of the other axis
ax1.set_title('zero')
ax1.spines['bottom'].set_position('zero')
ax1.spines['left'].set_position('zero')
ax1.set_ylim(-0.4,1.0)
# No ticklabels at zero
ax1.set_xticks([-10,-5,5,10,15,20])
ax1.set_yticks([-0.4,-0.2,0.2,0.4,0.6,0.8,1.0])
ax1.plot(x,y)
plt.show()
Final remark: If ax.spines['bottom'].set_position('zero')
is used but zerois not within the plotted y-range, then the axes is shown at the boundary of the plot closer to zero.
最后备注:如果ax.spines['bottom'].set_position('zero')
使用了但零不在绘制的 y 范围内,则轴显示在图的边界处更接近零。
回答by CodingYourLife
The title of this question is how to draw the spine in the middle and the accepted answer does exactly that but what you guys draw is the sigmoid function and that one passes through y=0.5. So I think what you want is the spine centered according to your data. Matplotlib offers the spine position datafor that (see documentation)
这个问题的标题是如何在中间绘制脊椎,接受的答案正是这样做的,但你们绘制的是 sigmoid 函数,该函数通过 y=0.5。所以我认为你想要的是根据你的数据以脊柱为中心。Matplotlib 提供了脊椎位置数据(见文档)
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
return 1 / (1 + np.exp(-x))
sigmoid = np.vectorize(sigmoid) #vectorize function
values=np.linspace(-10, 10) #generate values between -10 and 10
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
#spine placement data centered
ax.spines['left'].set_position(('data', 0.0))
ax.spines['bottom'].set_position(('data', 0.0))
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.plot(values, sigmoid(values))
plt.show()
Looks like this (Github):
看起来像这样(Github):