6

I created this Python function to generate a sigmoid function where I can modify position and width:

import numpy as np
import matplotlib.pyplot as plt


def sigmoid(x,a,b):
# sigmoid function with parameters a = center; b = width
return 1/(1+np.exp(-(x-a)/b))

For example changing the parameter b I can make it wider or narrower:

# testing changing sigmoid width (and slope at the same time) - parameter b
 x = np.linspace(0,10,256)
 y = sigmoid(x,5,1) # default
 ymax = sigmoid(x,5,1.75)
 ymin = sigmoid(x,5,0.25)
 # Create the plot
 plt.plot(x,y,lw=2,color='black')
 plt.plot(x,ymax,lw=2,color='green')
 plt.plot(x,ymin,lw=2,color='orange')

The above is fairly straightforward.

But what if I wanted a rotated sigmoid function? I simulated my intended result "graphically" in the figure below:

enter image description here

which I plotted by just creating a new independent variable x ('test' variable below) and swapping x and y:

test=np.linspace(0,1,128)
plt.plot(y2*255,test,lw=2,color='yellow')

Is there a way to achieve this shape with a new sigmoid-like function, or to rotate the original?

It has occurred to me that I could use something like -np.sinh(x) but what I'd really like is to have a similar exponential expression with parameters a and b to control the curve's shape.

This question is also posted on Stack Overflow https://stackoverflow.com/questions/25851287/how-to-generate-a-rotated-by-90-degrees-logistic-sigmoid-function-in-python

MyCarta
  • 163
  • 1
  • 5
  • What about applying a transformation (rotation in this case) to your $x-y$ data? – nicoguaro Sep 16 '14 at 18:42
  • Hi nicoguaro, that's one of the things I was thinking about but I don't have any prior experience with it. HOw would you do it? – MyCarta Sep 17 '14 at 02:09
  • You can rotate a vector with coordinates $(x,y)$ by an angle $\theta$ using a rotation matrix, like $$\begin{pmatrix} x' \ y' \end{pmatrix} = \begin{pmatrix} \cos\theta &-\sin\theta\ \sin\theta & \cos\theta \end{pmatrix} \begin{pmatrix} x \ y \end{pmatrix}$$ Just as described in Wikipedia. – nicoguaro Sep 17 '14 at 02:17
  • OK, I've use that before in other subject matters. I will give it a try, have to figure out how to do it in Python. Thanks a lot! – MyCarta Sep 17 '14 at 02:29
  • 1
    You can use numpy, like
    import numpy as np  
    R = np.array([[np.cos(t),-np.sin(t)],[np.sin(t),np.cos(t)]])  
    X_new = np.dot(R,X_old)  
    
    

    where X_old is a $2\times n$ array, $n$ the number of data you have.

    – nicoguaro Sep 17 '14 at 02:33
  • Looking good. Why don't you make this comment an answer? – MyCarta Sep 17 '14 at 03:03

2 Answers2

7

Are you sure you don't want the logit function?

k20
  • 772
  • 3
  • 3
3

I am turning my comments into an answer as a petition of Mycarta. One easy option that I would use is to rotate the $(x,y)$. To rotate a vector with coordinates $(x,y)$ by an angle $\theta$ you can use a rotation matrix $$\begin{pmatrix} x' \\ y' \end{pmatrix} = \begin{pmatrix} \cos\theta &-\sin\theta\\ \sin\theta & \cos\theta \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix}$$

In Python this can be easily done as

import numpy as np
R = np.array([[np.cos(t),-np.sin(t)],[np.sin(t),np.cos(t)]])
X_new = np.dot(R,X_old)

where X_old is a $2\times n$ array, being $n$ the number of data you have.

nicoguaro
  • 8,500
  • 6
  • 23
  • 49
  • Hi nicoguaro, I choose k20's answer as it is the best out of two valid solutions to my problem. As soon as my reputation reaches 15 I will come back and upvote your answer. And thanks for the explanations. – MyCarta Sep 19 '14 at 00:11