2015-07-22 16 views
9

Chcę narysować postać w matplotib gdzie oś są wyświetlane w samej działce nie po stronieRysunek oś w środku figue w Pythonie

Próbowałem następujący kod from

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

powyższy kod wyświetla postać jak ten enter image description here

Chciałbym wyciągnąć to coś w następujący sposób (obrazu z Wiki)

enter image description here

Spojrzenie na to question, rysuje linię odniesienia pośrodku, ale bez osi.

Każda pomoc będzie świetna!

Dzięki

Odpowiedz

14

Jednym ze sposobów, aby to zrobić jest użycie 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() 

pokazuje: enter image description here

+0

Dzięki, dokładnie to, czego szukam! – Shan

6

Zasadniczo, chcę wypowiedzieć się na temat akceptowanych odpowiedzi (ale nie mój rep pozwól na to). Zastosowanie

ax.spines['bottom'].set_position('center') 

wyciąga osi X tak, że przecinają osi Y w środku. W przypadku asymetrycznego ylim oznacza to, że oś X przechodzi NIE przez y = 0. Odpowiedź Jblasco ma tę wadę, przecięcie wynosi y = 0,5 (środek pomiędzy ymin = 0,0 i ymax = 1,0). Jednak wykres referencyjny oryginalnego pytania ma osie, które przecinają się nawzajem przy 0,0 (co jest jakoś konwencjonalne lub Najrzadszy). Aby uzyskać to zachowanie, należy użyć:

ax.spines['bottom'].set_position('zero') 

. Zobacz następujący przykład, w którym "zero" powoduje, że osie przecinają się w punkcie 0,0 mimo asymetrycznych zakresów zarówno wx jak iy.

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

Konkluzja: Jeżeli ax.spines['bottom'].set_position('zero') stosowano nie zerois w wykreślono y zakresem, których osie przedstawiono na granicy działki bliższa zeru.

4

Tytuł tego pytania brzmi: jak narysować kręgosłup w środku, a zaakceptowana odpowiedź robi dokładnie to, ale to, co rysujesz, to sigmoidalna funkcja, która przechodzi przez y = 0,5. Więc myślę, że to, czego chcesz, to kręgosłup wyśrodkowany zgodnie z Twoimi danymi. Matplotlib oferuje pozycję kręgosłupa danych za to (see documentation)

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

wygląda następująco (Github):

enter image description here