Python - Plot showing Empty - python

I am trying to plot the following:
#Time
for t in np.arange(1,10,1):
#Raidus
for r in np.arange(1,5,1):
#Velocity in theta direction
V = C/r*(1-np.exp(-r**2/(4*v*t)))
print(r,V)
#Vorticity
Z = C*((1/(2*v*t))*np.exp(-r**2/(4*v*t))-(1-np.exp(-r**2/(4*v*t)))/r**2)
plt.plot(r,V)
When I print(r,V) python does show 9 tables (each for a different t) with radius from 1-4.
However, when I plot, the plot looks completely empty.
Thanks for the help.

Save the r and the v in two lists.
Append the list in each loop with a new r and a new v.
After the interior loop, pass the lists to the plot and empty them.

Related

Plot overwriting in for loop

I'm using FeniCS to solve a PDE at different time-steps which I then store into various lists and plot in python using matplotlib. I'm having problems trying to create and save multiple (three) plots in a loop. I can only manage to save one plot without them overwriting. Neglecting necessary details, my code looks like this
for n in range(num_steps):
#Update current time
t += dt
#Solve
solve(a_form == L_form, u)
#Store times
t_vals.append(t)
#Solve PDE, gives solution u
solve(u)
#Create empty lists
u_vals_x = []
u_vals_y = []
u_vals_z = []
#Set constant
xyz_fixed_density = 1000
#Store u values varying x, y and z held equal to 1
for n in np.linspace(x0,x1,xyz_fixed_density):
u_vals_x.append(u(n,1,1))
#Store u values varying y, x and z held equal to 1
for n in np.linspace(y0,y1,xyz_fixed_density):
u_vals_y.append(u(1,n,1))
#Store u values varying z, x and y held equal to 1
for n in np.linspace(z0,z1,xyz_fixed_density):
u_vals_z.append(u(1,1,n))
#First plot
plt.scatter(np.linspace(x0,x1,xyz_fixed_density),u_vals_x,s=1)
plt.legend(t_vals)
plt.xlabel('$x$')
plt.ylabel('$u(t,x,1,1)$')
plt.savefig('u_vs_x.png')
#Second plot
plt.scatter(np.linspace(y0,y1,xyz_fixed_density),u_vals_y,s=1)
plt.legend(t_vals)
plt.xlabel('$y$')
plt.ylabel('$u(t,1,y,1)$')
plt.savefig('u_vs_y.png')
#Third plot
plt.scatter(np.linspace(z0,z1,xyz_fixed_density),u_vals_z,s=1)
plt.legend(t_vals)
plt.xlabel('$z$')
plt.ylabel('$u(t,1,1,z)$')
plt.savefig('u_vs_z.png')
It's probably a simple fix but I can't seem to get it to work. Thanks in advance.
Use the current iteration (n) as part of the filenames; e.g. replace
plt.savefig('u_vs_x.png')
with
plt.savefig(f'u_vs_x_{n}.png')
This uses the f-string syntax to format the code. If you’re using an older Python version which does not support f-strings yet, use format explicitly:
plt.savefig('u_vs_x_{}.png'.format(n))
You’ll also need to create a new plot each time, e.g. via
plt.figure()

Plotting subplots from a nested for loop in Python

I am trying to plot line plots(Drifted brownian motion) for different values of mu and sigma, I have a function that iterates a list of possible mu values and possible sigma values and it's supposed to then return the resulting plots. The problem is I am unsure how to make the subplots return the required number of rows. I have given it the correct nrows and ncols but the problem comes in with the indexing. Does anyone have a trick to solve this?
I have provided the code and the error message below,
# Drifted BM for varying values mu and sigma respectively
def DriftedBMTest2(nTraj=50,T=5.0,dt=0.01,n=5, sigma = [0.1,1.0,2], mulist=[0,0.5,1,1.5], ValFSize=(18,14)):
nMu = len(mulist)
nSigma = len(mulist)
# Discretize, dt = time step = $t_{j+1}- t_{j}$
dt = T/(n-1)
# Loop on different value sigma
for z in range(nSigma):
# Loop on different value Mu
for k in range(nMu):
n=int(T/dt)
x=np.zeros(n+1,float)
# Create plot space
temp = nSigma*nMu/2
plt.subplot(temp,2,k+1)
plt.title("Drifted BM $\sigma$={}, $\mu$={}".format(sigma[z],mulist[k]))
plt.xlabel(r'$t$')
plt.ylabel(r'$W_t$');
# Container for colours for each trajectory
colors = plt.cm.jet(np.linspace(0,1,nTraj))
# Generate many trajectories
for j in range(nTraj):
# Time simulation
# Add the time * constant(mu)
for i in range(n):
x[i+1]=x[i]+np.sqrt(dt)*np.random.randn() + i*mulist[k]
# Scale Each Tradjectory
x = x * sigma[z]
# Plot trajectory just computed
plt.plot(np.linspace(0,T,n+1),x,'b-',alpha=0.3, color=colors[j], lw=3.0)
DriftedBMTest2( sigma = [1,2], mulist=[-2,1] )
I then get the first two plots but not all of them and the error below.
MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.
Sorry if this is a bad question, I am new to Python but any help would be appreciated.
Try adding fig = plt.figure() between the two for loops
for z in range(nSigma):
# Loop on different value Mu
fig = plt.figure() # <---- Line added here
for k in range(nMu):
If that doesn't give the desired layout, you can try moving it to the inner for loop as
for z in range(nSigma):
# Loop on different value Mu
for k in range(nMu):
fig = plt.figure() # <---- Line added here

How to make a 2D plot with color density as the 3rd argument in python 3

I'd like to make a plot where each point it has its x&y value and it also has a third value expressing the color density at that point. Applying my python code in mathematica I am able to do it using the following code, but now I want to do it only using python(preferably using matlibplot).
def printMath2DTableMethod():
print('{', end="")
for i in range(0, lines, 1):
print('{', end="")
for j in range(0, columns, 1):
f = int(columns * rearrange_.rearrangeMethod(i) + rearrange_.rearrangeMethod(j))
print('%d' % size[f], end = '')
if (j < columns - 1):
print(',', end='')
if (i < lines - 1):
print('},')
else:
print('}}')
The plotting should look something similar to the images of these two questions
How can I make a scatter plot colored by density in matplotlib?
How to plot a density map in python?
it should have a colorbar at the side and the points with the biggest density should be on the top of the other points(if they overlap).
The data that this method produces I append it to some file and it looks like:
1,2,4,5,6,2,6 x256 columns in total
3,2,4,5,1,6,4
4,2,5,6,1,7,5
x256 rows in total
The plotting can be made by using the code directly or by reading the data from the file, but what I don't know is how to assign values to x(which is the i at the 1st for loop at the code above), to y(which is the j at the 2nd for loop at the code above) and especially to the 3rd argument, the one which will show the color density(which is the size[f] at the code above) since it is depended on i and j of the for loops.
I have been trying to research and solve it myself all these days, but not much success, so any help would be highly appreciated. Thanks in advance :)
Here are examples for both plots you linked
import matplotlib.pyplot as plt
import scipy as sp
# scatterplot as link 1
Data = sp.randn(1000,3)
plt.scatter(Data[:,0],Data[:,1],c=Data[:,2],cmap='magma')
plt.colorbar()
# density matrix as link 2
Nbins = 50
M = sp.zeros((Nbins+1,Nbins+1))
xinds = sp.digitize(Data[:,0],sp.linspace(-3,3,Nbins)) # chose limits accordingly
yinds = sp.digitize(Data[:,1],sp.linspace(-3,3,Nbins))
# to account for the highest density drawn over the others
sort_inds = sp.argsort(Data[:,2])[::-1]
Data = Data[sort_inds,:]
xinds = xinds[sort_inds]
yinds = yinds[sort_inds]
for i in range(Data.shape[0]):
M[xinds[i],yinds[i]] = Data[i,2]
plt.matshow(M,cmap='magma',
extent=(Data[:,0].min(),Data[:,0].max(),Data[:,1].max(),Data[:,1].min()),
aspect='equal')
plt.colorbar()

How to use matplotlib to plot only the last 50 values of growling lists?

I am trying to use matplotlib function in Python to interactively plot only the last 50 values of 2 growing lists while a loop goes on. However, once the size of the lists grow to more than 50, the values of the plot lines start overlapping.
I want to clear the overlapping.
Here is the photo of the plot at iteration < 50. Nice and clean.
Here is the photo of the plot at iteration > 50. You can see that it's getting messy.
Here is my code
import matplotlib.pyplot as plt
ls1 = []
ls2 = []
while True:
(some computation to get, in every iteration, 2 new values: ls1_new and ls2_new)
ls1.append(ls1_new)
ls2.append(ls2_new)
plt.plot(ls1[-50:])
plt.plot(ls2[-50:])
plt.draw()
plt.pause(0.0001)
Can anyone help me solve the overlapping part? Thanks ahead for the help! :)
Your problem is that you are creating new lines at every iteration. It would probably be nicer to update your existing lines instead. The code below will probably won't work straight away, but it should point you in the right direction. The general idea is to keep a reference to the Line2D object returned by plt.plot() and then using the member functions Line2D.set_data(x, y) or Line2D.set_ydata(y) to update the line at each iteration.
import matplotlib.pyplot as plt
ls1 = []
ls2 = []
l1, = plt.plot([])
l2, = plt.plot([])
while True:
(some computation to get, in every iteration, 2 new values: ls1_new and ls2_new)
ls1.append(ls1_new)
ls2.append(ls2_new)
l1.set_data(range(50),ls1[-50:])
l2.set_data(range(50),ls2[-50:])
plt.draw()
plt.pause(0.0001)

Plotting trajectories in python using matplotlib

I'm having some trouble using matplotlib to plot the path of something.
Here's a basic version of the type of thing I'm doing.
Essentially, I'm seeing if the value breaks a certain threshold (6 in this case) at any point during the path and then doing something with it later on.
Now, I have 3 lists set-up. The end_vector will be based on the other two lists. If the value breaks past 2 any time during a single simulation, I will add the last position of the object to my end_vector
trajectories_vect is something I want to keep track of my trajectories for all 5 simulations, by keeping a list of lists. I'll clarify this below. And, timestep_vect stores the path for a single simulation.
from random import gauss
from matplotlib import pyplot as plt
import numpy as np
starting_val = 5
T = 1 #1 year
delta_t = .1 #time-step
N = int(T/delta_t) #how many points on the path looked at
trials = 5 #number of simulations
#main iterative loop
end_vect = []
trajectories_vect = []
for k in xrange(trials):
s_j = starting_val
timestep_vect = []
for j in xrange(N-1):
xi = gauss(0,1.0)
s_j *= xi
timestep_vect.append(s_j)
trajectories_vect.append(timestep_vect)
if max(timestep_vect) > 5:
end_vect.append(timestep_vect[-1])
else:
end_vect.append(0)
Okay, at this part if I print my trajectories, I get something like this (I only posted two simulations, instead of the full 5):
[[ -3.61689976e+00 2.85839230e+00 -1.59673115e+00 6.22743522e-01
1.95127718e-02 -1.72827152e-02 1.79295788e-02 4.26807446e-02
-4.06175288e-02] [ 4.29119818e-01 4.50321728e-01 -7.62901016e-01
-8.31124346e-02 -6.40330554e-03 1.28172906e-02 -1.91664737e-02
-8.29173982e-03 4.03917926e-03]]
This is good and what I want to happen.
Now, my problem is that I don't know how to plot my path (y-axis) against my time (x-axis) properly.
First, I want to put my data into numpy arrays because I'll need to use them later on to compute some statistics and other things which from experience numpy makes very easy.
#creating numpy arrays from list
#might need to use this with matplotlib somehow
np_trajectories = np.array(trajectories_vect)
time_array = np.arange(1,10)
Here's the crux of the issue though. When i'm putting my trajectories (y-axis) into matplotlib, it's not treating each "list" (row in numpy) as one path. Instead of getting 5 paths for 5 simulations, I am getting 9 paths for 5 simulations. I believe I am inputing stuff wrong hence it is using the 9 time intervals in the wrong way.
#matplotlib stuff
plt.plot(np_trajectories)
plt.xlabel('timestep')
plt.ylabel('trajectories')
plt.show()
Here's the image produced:
Obviously, this is wrong for the aforementioned reason. Instead, I want to have 5 paths based on the 5 lists (rows) in my trajectories. I seem to understand what the problem is but don't know how to go about fixing it.
Thanks in advance for the help.
When you call np_trajectories = np.array(trajectories_vect), your list of trajectories is transformed into a 2d numpy array. The information about its dimensions is stored in np_trajectories.shape, and, in your case, is (5, 9). Therefore, when you pass np_trajectories to plt.plot(), the plotting library assumes that the y-values are stored in the first dimension, while the second dimension describes individual lines to plot.
In your case, all you need to do is to transpose your np_trajectories array. In numpy, it is as simple as
plt.plot(np_trajectories.T)
plt.xlabel('timestep')
plt.ylabel('trajectories')
plt.show()
If you want to plot the x-axis as time, instead of steps of one, you have to define your time progression as a list or an array. In numpy, you can do something like
times = np.linspace(0, T, N-1)
plt.plot(times, np_trajectories.T)
plt.xlabel('timestep')
plt.ylabel('trajectories')
plt.show()
which produces the following figure:

Categories