Как нарисовать ось в середине фигуры?
Я хочу нарисовать фигуру в Matplotib, где оси отображаются в самом графике, а не на стороне
Я попробовал следующий код отсюда:
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()
Приведенный выше код отображает рисунок следующим образом:
![]()
То, что я хотел бы нарисовать что-то следующее (изображение из Wiki)
![]()
Посмотрев на этот вопрос, он рисует контрольную линию в середине, но без оси.
Ответы
Ответ 1
Один из способов сделать это - 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()
показывает: ![enter image description here]()
Ответ 2
В принципе, я хочу прокомментировать принятый ответ (но мой представитель этого не допускает).
Использование
ax.spines['bottom'].set_position('center')
рисует оси x таким образом, что пересекает оси y в своем центре. В случае асимметричного ylim это означает, что ось x проходит через y = 0. Ответ Jblasco имеет этот недостаток, пересечение находится при y = 0,5 (центр между ymin = 0,0 и ymax = 1,0)
Однако ссылочный график исходного вопроса имеет оси, которые пересекаются друг с другом в 0,0 (что является как-то обычным или, по крайней мере, общим).
Чтобы достичь этого,
ax.spines['bottom'].set_position('zero')
.
См. Следующий пример, где "ноль" делает оси пересекающимися на 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()
Заключительное замечание: если используется ax.spines['bottom'].set_position('zero')
, но ноль не входит в график y-диапазона, то оси показаны на границе графика ближе к нулю.
Ответ 3
Название этого вопроса - как нарисовать позвоночник посередине, и принятый ответ делает именно это, но вы, ребята, рисуете сигмовидную функцию, которая проходит через у = 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()
Похоже на это (Github):
![enter image description here]()