Plotting a function in Python 2.7 - python

I am trying to plot f in this program but I am screwing something up. Can someone have a look and inform me as to where I am messing up. Thanks.
import math
#x is the horizontal distance that the ball has traveled
g=9.81
v=raw_input('Enter an initial velocity:')
theta=raw_input('Enter the angle that the object was thrown at:')
y=raw_input('Enter the initial position of the object on the y-axis:')
t=(2*v*math.sin(theta))/g
x=(0.5)*((v*math.sin(theta))+v)*t
float(v)
float(theta)
float(y)
float(t)
f=x*math.tan(theta)-(1/(2*(v**2)))*((g(x**2))/(math.cos(theta)**2))+y
figure(1)
clf()
plot(f)
xlabel('x')
ylabel('y')
show()

So first of all, I would import numpy and matplotlib
import numpy as np
import matplotlib.pyplot as plt
Then, you have to convert your string input into floats, for that you can use eval.
initial_velo = eval(raw_input("Whatever you like: "))
...
Then for plotting with matplotlib you actually have to create a list of values (just as when you collect real data and then type it into the computer and then plot the single data points). For that I like to use linspace from the numpy import:
time_steps = np.linspace(0, t, steps)
# steps gives the numbers of intervals your time from 0 to t is splitted into
Now you create your functions x and f as functions of t. They will also have to be of type list. And in the end you can plot what you want via:
plt.figure(1)
plt.plot(time_steps, f)
plt.xlabel("x")
plt.ylabel("y")
plt.show()
But maybe you should also watch how to plot stuff in the matplotlib doc. Also numpy has a great doc.

Related

How to render line plot with uncertainty in matplotlib

I am wondering whether I can plot a graph in which I show a range of best and worst results using matplotlib. The result should look something like this:
Image of the graph I want to replicate here.
You see the ranges around each point that specify what the best and worst measure is? This is exactly what I am looking for.
I'm pretty sure the errorbar function does exactly what you want:
https://matplotlib.org/3.5.0/api/_as_gen/matplotlib.pyplot.errorbar.html
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(10)
y = np.arange(10)
# yerr can be a single number or an array with same length as x and y
# depending on whether you want it to be constant or changing
yerr = 1
plt.errorbar(x, y, yerr=yerr)
plt.show()

Python code with for loop that did not work

I have run the following code but it showed an empty plot with nothing plotted and I am not able to know the reason
Please help
import matplotlib.pyplot as plt
import math
for xx in range(10,100000,1000):
plt.plot(xx,math.sqrt((.30*(1-.3))/(xx-1)))
If you are trying to plot each point individually, try using plt.scatter() like this:
for xx in range(10,100000,1000):
plt.scatter(xx, math.sqrt((.30*(1-.3))/(xx-1)))
If you're looking to plot a continuous line, you'll want to make your vectors beforehand and then pass them to plt.plot(). I suggest using numpy since np.arrays can handle vectorized data
import numpy as np
# Make x vector
xx = np.arange(10,100000,1000)
# Make y
y = np.sqrt((.30*(1-.3))/(xx-1))
# Plot
plt.plot(xx, y)
While the other answer solves the issue, you should know that your attempt was not completely wrong. You can use plt.plot to plot individual points in a for loop. However, you will have to specify the marker in that case. This can be done using, let's say, a blue dot using bo as
for xx in range(10,100000,1000):
plt.plot(xx,math.sqrt((.30*(1-.3))/(xx-1)), 'bo')
Alternatively, in addition to the other answer, you can simply use plt.scatter even for a whole array as following. Note, in this case you will have to use the sqrt module from NumPy as you are performing vectorized operation here which is not possible with math.sqrt
xx = np.arange(10,100000,1000)
plt.scatter(xx,np.sqrt((.30*(1-.3))/(xx-1)), c='green', edgecolor='k')

Tracing functions in python

I was searching about how to trace function graphs, but not only linear ones, I know how to plot with simple points, they are the linear ones like this one below:
import numpy
import matplotlib.pyplot as plt
%matplotlib inline
_=plt.plot([4,7],[5,7],color ='w')
_=plt.plot([4,7],[7,7],color ='w')
ax = plt.gca()
ax.set_facecolor('xkcd:red')
plt.show()
then after a bit of searching, I've found this code:
import pylab
import numpy
x = numpy.linspace(-15,15,100) # 100 linearly spaced numbers
y = numpy.sin(x)/x # computing the values of sin(x)/x
# compose plot
pylab.plot(x,y) # sin(x)/x
pylab.plot(x,y,'co') # same function with cyan dots
pylab.plot(x,2*y,x,3*y) # 2*sin(x)/x and 3*sin(x)/x
pylab.show() # show the plot
That works perfectly! But what I'm wondering is: do we really need to use standard functions that have defined by Numpy?( like sin(x)/x here ) Or can we define a function ourselves and use it in Numpy function too, like x**3?
This solved issue, Thanks FlyingTeller
An example of y=x**3 graph:
import pylab
import numpy
x = numpy.linspace(-15,15,100) # 100 linearly spaced numbers
y = x**3 # we change this to tracer graphs as we want
# compose plot
pylab.plot(x,y)
pylab.show()

How to extract x,y data from kdensity plot from matplotlib for python

I am trying to figure out how to make a 3d figure of uni-variate kdensity plots as they change over time (since they pull from a sliding time window of data over time).
Since I can't figure out how to do that directly, I am first trying to get the x,y plotting data for kdensity plots of matplotlib in python. I hope after I extract them I can use them along with a time variable to make a three dimensional plot.
I see several posts telling how to do this in Matlab. All reference getting Xdata and Ydata from the underlying figure:
x=get(h,'Xdata')
y=get(h,'Ydata')
How about in python?
The answer was already contained in another thread (How to create a density plot in matplotlib?). It is pretty easy to get a set of kdensity x's and y's from a set of data.
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde
data = [1.5]*7 + [2.5]*2 + [3.5]*8 + [4.5]*3 + [5.5]*1 + [6.5]*8 # data is a set of univariate data
xs = np.linspace(0,max(data),200) # This 200 sets the # of x (and so also y) points of the kdensity plot
density = gaussian_kde(data)
density.covariance_factor = lambda : .25
density._compute_covariance()
ys = density(xs)
plt.plot(xs,ys)
And there you have it. Both the kdensity plot and it's underlying x,y data.
Not sure how kdensity plots work, but note that matplotlib.pyplot.plot returns a list of the added Line2D objects, which are, in fact, where the X and Y data are stored. I suspect they did that to make it work similarly to MATLAB.
import matplotlib.pyplot as plt
h = plt.plot([1,2,3],[2,4,6]) # [<matplotlib.lines.Line2D object at 0x021DA9F0>]
x = h[0].get_xdata() # [1,2,3]
y = h[0].get_ydata() # [2,4,6]

How to update 3D arrow animation in matplotlib

I am trying to reproduce the left plot of this animation in python using matplotlib.
I am able to generate the vector arrows using the 3D quiver function, but as I read here, it does not seem possible to set the lengths of the arrows. So, my plot does not look quite right:
So, the question is: how do I generate a number of 3D arrows with different lengths? Importantly, can I generate them in such a way so that I can easily modify for each frame of the animation?
Here's my code so far, with the not-so-promising 3D quiver approach:
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d
ax1 = plt.subplot(111,projection='3d')
t = np.linspace(0,10,40)
y = np.sin(t)
z = np.sin(t)
line, = ax1.plot(t,y,z,color='r',lw=2)
ax1.quiver(t,y,z, t*0,y,z)
plt.show()
As Azad suggests, an inelegant, but effective, solution is to simply edit the mpl_toolkits/mplot3d/axes3d.py to remove the normalization. Since I didn't want to mess with my actual matplotlib installation, I simply copied the axes3d.py file to the same directory as my other script and modified the line
norm = math.sqrt(u ** 2 + v ** 2 + w ** 2)
to
norm = 1
(Be sure to change the correct line. There is another use of "norm" a few lines higher.) Also, to get axes3d.py to function correctly when it's outside of the mpl directory, I changed
from . import art3d
from . import proj3d
from . import axis3d
to
from mpl_toolkits.mplot3d import art3d
from mpl_toolkits.mplot3d import proj3d
from mpl_toolkits.mplot3d import axis3d
And here is the nice animation that I was able to generate (not sure what's going wrong with the colors, it looks fine before I uploaded to SO).
And the code to generate the animation:
import numpy as np
import matplotlib.pyplot as plt
import axes3d_hacked
ax1 = plt.subplot(111,projection='3d')
plt.ion()
plt.show()
t = np.linspace(0,10,40)
for index,delay in enumerate(np.linspace(0,1,20)):
y = np.sin(t+delay)
z = np.sin(t+delay)
if delay > 0:
line.remove()
ax1.collections.remove(linecol)
line, = ax1.plot(t,y,z,color='r',lw=2)
linecol = ax1.quiver(t,y,z, t*0,y,z)
plt.savefig('images/Frame%03i.gif'%index)
plt.draw()
plt.ioff()
plt.show()
Now, if I could only get those arrows to look prettier, with nice filled heads. But that's a separate question...
EDIT: In the future, matplotlib will not automatically normalize the arrow lengths in the 3D quiver per this pull request.
Another solution is to call ax.quiever on each arrow, individually - with each call having an own length attribute. This is not very efficient but it will get you going.
And there's no need to change MPL-code

Categories