Tracing functions in python - 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()

Related

How can force python matplotlib to axis to scale linearly?

So here is my python code.
import matplotlib.pyplot as plt
M=[]
for i in np.arange(0.01,8,0.01):
M.append(test(i))
plt.plot(M)
plt.grid(b=True,which="major",color='#666666', linestyle='-',linewidth=0.2)
plt.show()
Where test(x) is some complicated function.
When i try to plot it python for some plots on X-axis from 1 to 800, but i want have scaled it plot from 0.01 to 8. So scaled down without changing graph.
Due to complicated form of test(x) function, i would like to use arrays, and this method of ploting.
Add an index to plot against (essentially your x-axis values):
import matplotlib.pyplot as plt
M=[]
indices = []
for i in np.arange(0.01,8,0.01):
M.append(test(i))
indices.append(i)
plt.plot(indices, M)
plt.grid(b=True,which="major",color='#666666', linestyle='-',linewidth=0.2)
plt.show()

Pyplot: How to make a colorbar with a nonlinear scale?

I want to add to my plot a colorbar, which has a nonlinear scale. For example, for such a plot:
I would like to have just 5 different colors on the bar on the right-hand side, instead of the gradient (don't pay attention to the plot itself; it's just an example).
I don't want to use contourf and would like to find some more general solution.
If you want to have discrete values in your colorbar, a quick way to do this would be to use the cmap=plt.cm.get_cmap() function and pass the name of whatever colormap class you are working with, along with the desired number of bins.
import matplotlib.pyplot as plt
plt.style.use('classic')
%matplotlib inline
import numpy as np
# Random Data Visualation
x = np.linspace(0, 10, 1000)
data = np.sin(x) * np.cos(x[:, np.newaxis])
plt.imshow(data, cmap=plt.cm.get_cmap('viridis', 5))
plt.colorbar()
plt.clim(-1, 1);
More documentation on everything color maps in Matplotlib [here]

Only point or scatter plot allowed in Python: plotting eigenvalues in a loop

I have the following simple code:
import numpy as np
import matplotlib.pyplot as plt
from scipy import linalg
for i in range(10):
M=np.array([[i**2,0],[0,i**3]]) # 2 x 2 matrix
eval,evec=np.linalg.eig(M)
# Plotting first and second eigenvalues
# Style 1
plt.plot(i,eval[0])
plt.plot(i,eval[1])
# Doesn't work
# Style 2
plt.plot(i,eval[0], '-r')
plt.plot(i,eval[1], '-b')
# Doesn't work
# Style 3
plt.plot(i,eval[0], 'ro-')
plt.plot(i,eval[1], 'bs')
# Does work
plt.xlabel('x')
plt.ylabel('y')
plt.savefig('plot.png')
plt.show()
While plotting with three different styles, only the third style (i.e. point or scatter plots) works successfully. Hence I have very limited customization options. Any way out?
Also, can these three differently styled plots be saved into three different files without creating separately three for-loops?
Output attached below.
Move the plotting outside the loop where computation occurs. In order to plot connected lines the plot function is expecting an array of values.
import numpy as np
import matplotlib.pyplot as plt
from scipy import linalg
yvals=[]
for i in range(10):
M=np.array([[i**2,0],[0,i**3]]) # 2 x 2 matrix
eval_,evec=np.linalg.eig(M)
yvals.append(eval_)
yvals=np.array(yvals)
xvals=np.array(range(10))
plt.plot(xvals,yvals[:,0],'-r')
plt.plot(xvals,yvals[:,1],'-b')
All of your plotting styles should work now.

Plotting a function in Python 2.7

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.

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