Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate random points above and below a line in Python

Tags:

python

random

I would like to generate random points on an x,y scatter plot that are either above or below a given line. For example, if the line is y=x I would like to generate a list of points in the top left of the plot (above the line) and a list of points in the bottom right of the plot (below the line). Here's is an example where the points are above or below y=5:

import random
import matplotlib.pyplot as plt

num_points = 10
x1 = [random.randrange(start=1, stop=9) for i in range(num_points)]
x2 = [random.randrange(start=1, stop=9) for i in range(num_points)]
y1 = [random.randrange(start=1, stop=5) for i in range(num_points)]
y2 = [random.randrange(start=6, stop=9) for i in range(num_points)]

plt.scatter(x1, y1, c='blue')
plt.scatter(x2, y2, c='red')
plt.show()

Random point plot

However, I generated the x and y points independently, which limits me to equations where y = c (where c is a constant). How can I expand this to any y=mx+b?

like image 376
jss367 Avatar asked Sep 26 '17 03:09

jss367


People also ask

How do you create a random list for specified range with random?

Use a random.randrange() function to get a random integer number from the given exclusive range by specifying the increment. For example, random.randrange(0, 10, 2) will return any random number between 0 and 20 (like 0, 2, 4, 6, 8).

How does Python generate 5 random numbers?

The randint() method to generates a whole number (integer). You can use randint(0,50) to generate a random number between 0 and 50. To generate random integers between 0 and 9, you can use the function randrange(min,max) . Change the parameters of randint() to generate a number between 1 and 10.


3 Answers

You can change the stop and start limits for y1 and y2 to be the line you want. You will need to decide where the plane ends (set lower and upper).

Note this only works for integers. You can use truncated multivariate distributions if you want something more sophisticated.

m, b = 1, 0
lower, upper = -25, 25

x1 = [random.randrange(start=1, stop=9) for i in range(num_points)]
x2 = [random.randrange(start=1, stop=9) for i in range(num_points)]

y1 = [random.randrange(start=lower, stop=m*x+b) for x in x1]
y2 = [random.randrange(start=m*x+b, stop=upper) for x in x2]

plt.plot(np.arange(10), m*np.arange(10)+b)
plt.scatter(x1, y1, c='blue')
plt.scatter(x2, y2, c='red')

enter image description here

like image 186
Gerges Avatar answered Sep 18 '22 18:09

Gerges


You may as well have my answer too.

This way puts Gaussian noise above the line, and below. I have deliberately set the mean of the noise to 20 so that it would stand out from the line, which is y = 10*x + 5. You would probably make the mean zero.

>>> import random
>>> def y(x, m, b):
...     return m*x + b
... 
>>> import numpy as np
>>> X = np.linspace(0, 10, 100)
>>> y_above = [y(x, 10, 5) + abs(random.gauss(20,5)) for x in X]
>>> y_below = [y(x, 10, 5) - abs(random.gauss(20,5)) for x in X]
>>> import matplotlib.pyplot as plt
>>> plt.scatter(X, y_below, c='g')
>>> plt.scatter(X, y_above, c='r')
>>> plt.show()

Here's the plot.

scatter plot

like image 31
Bill Bell Avatar answered Sep 21 '22 18:09

Bill Bell


There are many approaches possible, but if your only requirement is that they are above and below the y = mx + b line, then you can simply plug the random x values into the equation and then add or subtract a random y value.

import random
import matplotlib.pyplot as plt

slope = 1
intercept = 0

def ymxb(slope, intercept, x):
    return slope * x + intercept

num_points = 10
x1 = [random.randrange(start=1, stop=9) for i in range(num_points)]
x2 = [random.randrange(start=1, stop=9) for i in range(num_points)]
y1 = [ymxb(slope, intercept, x) - random.randrange(start=1, stop=9) for x in x1]
y2 = [ymxb(slope, intercept, x) + random.randrange(start=1, stop=9) for x in x2]

plt.scatter(x1, y1, c='blue')
plt.scatter(x2, y2, c='red')
plt.show()

That looks like this:

enter image description here

like image 33
Philip B. Avatar answered Sep 18 '22 18:09

Philip B.