Scatter animation in Python - python

I am attempting to animate a scatter plot in Python 3.6 (in Spyder IDE), for which there are several tutorials/examples (a, b, c, and many others), however my update function is somehow receiving a very different set of coordinates from what I think I'm providing.
The following is a reduced example code wherein 4 points proceed toward the center. I plot it twice, first as a line, second as an animation. The line plot looks right, but the animation shows very different behavior, both in terms of the locations of the points and their trajectories. I infer that I'm incorrectly supplying coordinate information to the update function, but I cannot seem to determine why/how.
I can supply figures showing what does vs. should happen, though I'll simply supply this sample code for now for brevity's sake.
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.animation as anim
npt=4
ntime=101
solx=np.zeros((npt,ntime))
soly=np.zeros((npt,ntime))
solx[0,0:]=np.linspace(0,40,ntime)
solx[1,0:]=solx[0,0:];
solx[2,0:]=100-solx[0,0:];
solx[3,0:]=solx[2,0:]
soly[0,0:]=np.linspace(0,80,ntime)
soly[1,0:]=200-soly[0,0:]
soly[2,0:]=soly[0,0:]
soly[3,0:]=soly[1,0:]
#%% Plots
colord=mpl.cm.gist_ncar(np.linspace(0,0.9,npt))
of2,oa2=plt.subplots(1)
for cnt in range(0,npt): oa2.plot(solx[cnt,0:],soly[cnt,0:],c=colord[cnt])
of3,oa3=plt.subplots()
osc3=oa3.scatter(solx[0:,0],soly[0:,0],c=colord,marker='+')
def aninit():
osc3.set_offsets(np.stack((solx[0:,0],soly[0:,0]),axis=0))
return osc3,
def aniupdate(i):
osc3.set_offsets(np.stack((solx[0:,i],soly[0:,i]),axis=0))
return osc3,
ani=anim.FuncAnimation(of3,aniupdate,init_func=aninit,frames=range(0,ntime),interval=100,blit=True,repeat=True,repeat_delay=1000)
plt.show()

If you replace
np.stack((solx[0:,0],soly[0:,0]),axis=0)
np.stack((solx[0:,i],soly[0:,i]),axis=0)
with:
list(zip(solx[0:,0],soly[0:,0]))
list(zip(solx[0:,i],soly[0:,i]))
or (if you want to use numpy arrays instead of lists:
np.array([solx[0:,0],soly[0:,0]]).T
np.array([solx[0:,i],soly[0:,i]]).T
in the aninit() and aniupdate(i) functions the behaviour should be as expected.
Here's the code I used to make the plots:
def aninit():
offsetlist = np.array([solx[0:,0],soly[0:,0]]).T
osc3.set_offsets(offsetlist)
return osc3,
def aniupdate(i):
offsetlist = np.array([solx[0:,i],soly[0:,i]]).T
osc3.set_offsets(offsetlist)
return osc3,

Related

How to hold single point plots in python?

Is there any way to hold all the plots together (every plot is a point) in the following code:
import numpy as np
import matplotlib.pyplot as plt
g=10.7247;
x0=0;
z0=30;
v0=100*0.4889;
theta=np.pi/5;
vx=v0*np.cos(theta);
vz=v0*np.sin(theta);
for t in np.arange(0,10,0.1):
x=x0+vx*t;
z=z0+vz*t-1/2*g*t**2;
plt.scatter(x,z)
plt.xlim(0,300)
plt.ylim(0,100)
plt.pause(0.01)
if z<0:
break;
plt.show()
I used the plt.plot because I want the points to present one after the other but without any hold feature it returns a moving point. I want it to be like an animation. Every point should appear after 0.01s.
Here is exactly what I want: https://youtu.be/CK7Zq0kGiLY

Plot scatter graphs with matplotlib subplot

I am trying to plot a scatter diagram. It will take multiple arrays as input but plot into a single graph.
Here is my code:
import numpy as np
import os
import matplotlib.pyplot as plt
ax = plt.gca()
n_p=np.array([17.2,25.7,6.1,0.9,0.5,0.2])
n_d=np.array([1,2,3])
a_p=np.array([4.3,1.4,8.1,1.8,7.9,7.0])
a_d=np.array([12,13,14])
ax.scatter = ([n_d[0]/n_d[1]],[n_p[0]/n_p[1]])
ax.scatter = ([a_d[0]/a_d[1]],[a_p[0]/a_p[1]])
I will read the arrays from csv file, here I just put a simple example (for that I imported os). I want to plot the ratio of array element 2/ element 1 of n_p (as x-axis) and same with n_d (as y-axis). This will give a point in the graph. Similar operation will be followed by a_p and a_d array, and the point will be appended to the graph. There will be more data to append, but to understand the process, two is enough.
I tried to follow example from here.
If I use the color, I get syntax error.
If I do not use color, I get a blank plot.
Sorry, my coding experience is beginner so code is rather nasty.
Thanks in advance.
remove the = from the function call!
import numpy as np
import os
import matplotlib.pyplot as plt
ax = plt.gca()
n_p=np.array([17.2,25.7,6.1,0.9,0.5,0.2])
n_d=np.array([1,2,3])
a_p=np.array([4.3,1.4,8.1,1.8,7.9,7.0])
a_d=np.array([12,13,14])
ax.scatter([n_d[0]/n_d[1]],[n_p[0]/n_p[1]])
ax.scatter([a_d[0]/a_d[1]],[a_p[0]/a_p[1]])

How to plot a line graph of density over a density colour map plot in Python

First time user so apologies for any mistakes.
I have some code (pasted below) which is used to analyse and gain values/graphs from a simulation I have run.
This results in the following image:
I would therefore now like to plot a line graph on top of this according to the values of the colour map corresponding to r = 0 on the y-axis at every point on the x - axis with each respective value on the colour map. However, I'm completely lost on where to even begin with this. I've tried looking into KDE and other similar things, but I realise I'm not sure how to take numerical values which were used to generate the colour map.
from openpmd_viewer import OpenPMDTimeSeries
from openpmd_viewer.addons import LpaDiagnostics
import numpy as np
from scipy.constants import c, e, m_e
import matplotlib.pyplot as plt
from matplotlib import gridspec
# Replace the string below, to point to your data
ts = OpenPMDTimeSeries(r"/Users/bentorrance/diags/hdf5/")
ts_2d = LpaDiagnostics(r"/Users/bentorrance/diags/hdf5/")
plt.figure(1)
Ez = ts.get_field(iteration=5750, field='E', coord='z', plot=True, cmap='inferno')
plt.title(r'Electric Field Density $E_{z}$')
plt.show()

Python - Not able to plot graph from a numpy array

I am trying plot a graph with a numpy array but the error occur in plt.plot(s,s).
import numpy as np
import matplotlib.pyplot as plt
def npArrDefine():
np.array=[]
s=np.array
for i in range(10):
s.append(i+3)
plt.plot(s,s)
plt.axis([0,5,0,20])
plt.show()
npArrDefine()
There's a lot of things wrong with your code.
np.array=[] and s=np.array. Here, you are setting a name that numpy uses to be an empty list (horrible!), and then you are setting s to be that empty list. Don't do this. Simply do s=[].
Later on you are trying to plot by using plt.plot(s,s) which means you want to plot s against itself. This will always give you a straight 45 degree line with 0 intercept even if your code worked.
Your code block should be:
s=[]
for i in range(10):
s.append(i+3)
s = np.array(s) #This line is optional, pyplot can use any array-like.
plt.plot(s)
...

matplotlib NaN's vs pylab NaN's

I have two similar pieces of matplotlib codes that produce different results.
1:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,10,100)
y = np.linspace(0,10,100)
y[10:40] = np.nan
plt.plot(x,y)
plt.savefig('fig')
2:
from pylab import *
x = linspace(0,10,100)
y = linspace(0,10,100)
y[10:40] = np.nan
plot(x,y)
savefig('fig')
Code #1 produces a straight line with the NaN region filled in with a solid line of a different color
Code #2 produces a figure with a straight line but does not fill in the NaN region with a line. Instead there is a gap there.
How can I make code # 1 produce a gap in place of NaN's like code #2. I have been googling for a couple of days and have come up with nothing. Any help or advice would be appreciated. Thanks in advance
Just to explain what's probably happening:
The two pieces of code you showed are identical. They will always produce the same output if called by themselves. pylab is basically a just a few lines of code that does: (There's a bit more to it than this, but it's the basic idea.)
from numpy import *
from matplotlib.mlab import *
from matplotlib.pyplot import *
There's absolutely no way for pylab.plot to reference a different function than plt.plot
However, if you just call plt.plot (or pylab.plot, they're the same function), it plots on the current figure.
If you plotted something on that figure before, it will still be there. (If you're familiar with matlab, matplotlib defaults to hold('on'). You can change this with plt.hold, but it's best to be more explicit in python and just create a new figure.)
Basically, you probably did this:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0,10,100)
y = np.linspace(0,10,100)
plt.plot(x,y)
plt.savefig('fig')
And then, in the same interactive ipython session, you did this:
y[10:40] = np.nan
plt.plot(x, y)
plt.savefig('fig')
Because you didn't call show, the current figure is still the same one as it was before. The "full" line is still present beneath the second one, and the second line with the NaN's is a different color because you've plotted on the same axes.
This is one of the many reasons why it's a good idea to use the object-oriented interface. That way you're aware of exactly which axes and figure you're plotting on.
For example:
fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig('test.png')
If you're not going to do that, at very least always explicitly create a new figure and/or axes when you want a new figure. (e.g. start by calling plt.figure())

Categories

Resources