Rewriting R plot code into Python using Matplotlib but not getting same results

Viewed 69

I've tried to rewrite code for a plot from R into Python, but have gotten a resulting diagram that doesn't look right. The dots of the Python scatter plot seem to fall on one line. Am wondering if I've used the wrong function in np.random.normal in replacing rnorm?

Here's the original R code:

g <- 9.8 ##meters per second
n <- 25
tt <- seq(0,3.4,len=n) ##time in secs, t is a base function
f <- 56.67  - 0.5*g*tt^2
y <-  f + rnorm(n,sd=1)

plot(tt,y,ylab="Distance in meters",xlab="Time in seconds")
lines(tt,f,col=2)

Here's the attempted rewrite in Python:

import numpy as np
import matplotlib.pyplot as plt
g = 9.8 # meters per second
n = 25 
tt = np.linspace(0, 3.4, num = n) 
f = 56.67 - 0.5 * g * tt**2
y = f + np.random.normal(n, scale=1.0)

plt.scatter(tt, y, edgecolor="black", facecolors="white")
plt.plot(tt, f, color="orange")
plt.xlabel("Time in seconds")
plt.ylabel("Distance in meters")
plt.show()

The first one's the R (desired) plot: Here's the R plot

Here's however the Python plot: Here's the Python plot

1 Answers

You are passing the arguments to np.random.normal() in the wrong order. The first argument is the mean of the sample, which you are currently giving as 25 and so your both curves are largely offset

The correct way is to pass the size of your desired random array as the last argument size=n

y = f + np.random.normal(scale=1.0, size=n) 

where size is the number of elements. The official docs state the following:

Parameters:
loc : float or array_like of floats Mean (“centre”) of the distribution.

scale : float or array_like of floats Standard deviation (spread or “width”) of the distribution.

size : int or tuple of ints, optional Output shape. If the given shape is, e.g., (m, n, k), then m * n * k samples are drawn. If size is None (default), a single value is returned if loc and scale are both scalars. Otherwise, np.broadcast(loc, scale).size samples are drawn.

Related