Pyplot Not Displaying My Graph - python

I'm trying to graph the recaman sequence as a scatter plot and as far as I can tell my script is setup correctly. Also I'm pretty sure its not the back-end because I can run scripts like:
import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.ylabel('some numbers')
plt.show()
and it works fine. Here's what my code looks like:
import matplotlib.pyplot as plt
import os
while(True):
try:
itterations = int(input("Itterations: "))
break
except ValueError:
os.system("cls")
def recaman(n):
arr = [0] * n
arr[0] = 0
for i in range(1, n):
curr = arr[i-1] - i
for j in range(0, i):
if ((arr[j] == curr) or curr < 0):
curr = arr[i-1] + i
break
arr[i] = curr
return(arr)
def genX(n):
x = []
for i in range(0,n):
i += 1
x.append(i)
return(x)
xaxis = genX(itterations)
yaxis = recaman(itterations)
for i in range (0,itterations):
plt.plot(xaxis[i],yaxis[i])
plt.show()

Instead of plotting individual invisible points in the loop, plot the whole curve with plt.plot(xaxis,yaxis) or (better) plt.scatter(xaxis,yaxis).
If you prefer to plot the individual points, at least make them visible:
for i in range (0,itterations):
plt.plot(xaxis[i],yaxis[i],"o")
plt.show()

Related

Plot a graph with incoming random data in python

I am trying to plot a graph for the data being produced using the following code.
import time
import random
import datetime
mylist = []
ct = datetime.datetime.now()
for i in range(0,61):
x = random.randint(1,100)
mylist.append(x)
if len(mylist) == 11:
right_in_left_out = mylist.pop(0)
else:
right_in_left_out = None
print(mylist)
time.sleep(1)
I want the graph to show real time plotting and at one time only 10 points should be plotted. The graph should keep moving forward just like how to data is being printed. Almost like an animation.
As Julien stated already, the linked complex example is probably what you are looking for.
Taking your code as a basis and assuming that you mixed up x- and y-coordinates, are you looking for something like this?
import time
import random
import datetime
import matplotlib.pyplot as plt
def redraw_figure():
plt.draw()
plt.pause(0.00001)
mylist = []
ct = datetime.datetime.now()
#initialize the data
xData = []
x = np.arange(0,10,1)
y = np.zeros(10)
#plot the data
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_ylim([0, 100])
ax.set_xlim([0, 10])
line, = ax.plot(x, y)
for i in range(0,61):
y = random.randint(1,100)
mylist.append(y)
if len(mylist) == 11:
right_in_left_out = mylist.pop(0)
else:
right_in_left_out = None
xData.append(i)
#draw the data
line.set_ydata(mylist)
line.set_xdata(xData)
redraw_figure()
print(mylist)
time.sleep(1)

How can I add a new plots to existing figures?

I am new to Python and have mainly used MatLab in the past. I am re-writing one of my MatLab scripts and am wondering how to add plots to figures. It seems in python I can only have one figure open at a time and have to manually close the window before a second figure will open. My original script is a couple hundred lines long, but here is a MWE of what I want to do.
import matplotlib.pyplot as plt
import numpy as np
#from mpl_toolkits import mplot3d
lst = [ 1, 1.5, 2, 4.5]
alpha= np.array(lst)
#initialize tables for plots
xtable = []
ytable = []
y2table = []
#determine whether lst is a vector or an array for number of iterations of inner and outer loops
def size(arr):
if len(arr.shape) == 1:
return arr.shape[0], 1
return arr.shape
[nn,mm] = size(alpha)
#create and plot data
for kk in range(nn):#= 1:nn
x = [i for i in range(0, 10)]
y = [alpha[kk]*i for i in range(0, 10)]
y2 = [alpha[kk]*i**2 for i in range(0, 10)]
#data for plot(s)
xtable += [x]
ytable += [y]
y2table += [y2]
#plot1
plt.plot(xtable,ytable)
plt.hold on
#plot2
plt.plot(xtable,y2table)
plt.hold on
In my script these will actually be 3D plots, but I don't think that's necessary here. I just want the for-loop to run for each value in lst and end up with two figures, each with 4 plots. The size of lst is not fixed or I'd generate the data in the loop and plot later.
Thank you in advance for your help
follow up on tdy's comment:
#create plots:
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
#plot data
for kk in range(nn):#= 1:nn
x = [i for i in range(0, 10)]
y = [alpha[kk]*i for i in range(0, 10)]
y2 = [alpha[kk]*i**2 for i in range(0, 10)]
#data for plot(s)
xtable += [x]
ytable += [y]
y2table += [y2]
#plot1
ax1.plot(xtable,ytable)
#plot2
ax2.plot(xtable,y2table)

How to connect dots with a line in real time using matplotlib

I'm writting a "3x+1" simulation code using matplotlib just for fun. I'm trying to make the values appear in real time and connected by a line. But I only get the scatter dots.
Code:
import matplotlib.pyplot as plt
plots = []
def three(x):
if x == 1:
return x
if x % 2 == 0:
plots.append(x/2)
return three(x/2)
else:
plots.append(3*x+1)
return three(3*x+1)
num = int(input('Number: '))
plots.append(num)
three(num)
y = []
x = [x for x in range(len(plots)+1)]
x.pop(0)
for i in plots:
plt.plot(x[plots.index(i)], i, ".-")
plt.pause(0.05)
plt.show()
Could you try this? I am thinking the render of plt.Show is occurring after all the pauses are looped. edit- sorry I see now you are asking about connecting the plots.
for i in plots:
plt.plot(x[plots.index(i)], i, ".-")
plt.pause(0.05)
plt.show()
I think your marker string is wrong found here. Try this
plt.plot(x[plots.index(i)], i, "-.")

How to update a plot by calling data from within the program?

I am writing a programme which takes a circular membrane and models its evolution under certain forces. The programme is as follows (with the details of the evolution omitted)
import numpy as np
import math
from matplotlib import pyplot as plt
xCoords = {"%s" % i: np.array([math.cos(2*math.pi*i/360),0,0,0,0,0,0,0,0,0], dtype=float)
for i in range(0, 360)} #coordinates stored in arrays whose entries correspond to time evolution
yCoords = {"%s" % i: np.array([math.sin(2*math.pi*i/360),0,0,0,0,0,0,0,0,0], dtype=float)
for i in range(0, 360)}
#fill out arrays using diff eq.
x = np.zeros((360,10), dtype = float)
y = np.zeros((360,10), dtype = float)
for i in range(0,360):
for j in range(0,10):
x[i][j] = xCoords["%s" % i][j]
y[i][j] = yCoords["%s" % i][j]
If I want to now plot the evolution of the coordinates over time, how would I do that?
I tried to plot with the following.
plt.plot(x,y)
plt.show
but it just outputs
In particular, how do I get a plot of just (x[i][j],y[i][j]) at time j?
I then tried
for j in range(0,62):
for i in range(0,360):
plt.plot(x[i][j],y[i][j])
plt.show()
but that didn't work either as it didn't give a new 'circle' everytime.
I think you are looking for something like this:
fig = plt.figure()
ax = fig.gca()
h, = ax.plot([],[])
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
for time_ind in range(0,10):
h.set_data(x[:, time_ind], y[:, time_ind])
plt.draw()
plt.pause(0.5)

Updating items on a grid dynamically within a for loop (python)

I’m trying to update a plot dynamically within a for loop and I can’t get it to work. I wonder if anyone can help?
I get a bit confused between passing the figure vs axes and how to update. I’ve been trying to use
display.clear_output(wait=True)
display.display(plt.gcf())
time.sleep(2)
but it’s not doing what I want it to.
I'm trying to:
1. add objects to a grid (setupGrid2)
2. at a timestep - move each object in random direction (makeMove2)
3. update the position of each object visually on the grid (updateGrid2)
My problem is with 3. I'd like to clear the previous step, so that just the new location for each object is displayed. The goal to show the objects dynamically moving around the grid.
I'd also like to work with the ax object created in setupGrid2, so that I can set the plot variables (title, legend etc.) in one place and update that chart.
Grateful for any help.
Sample code below (for running in jupyter notebook):
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import time
import pylab as pl
from IPython import display
def setupGrid2(norows,nocols,noobjects):
#each object needs current grid position (x and y coordinate)
objects = np.zeros(noobjects)
ObjectPos = np.zeros(shape=(noobjects,2))
#put objects randomly on grid
for i in range (noobjects):
ObjectPos[i][0] = np.random.uniform(0,norows)
ObjectPos[i][1] = np.random.uniform(0,nocols)
#plot objects on grid
fig = plt.figure(1,figsize=(15,5))
ax = fig.add_subplot(1,1,1)
x,y = zip(*ObjectPos)
ax.scatter(x, y,c="b", label='Initial positions')
ax.grid()
plt.show()
return ax,ObjectPos
def updateGrid2(ax,ObjPos):
x,y = zip(*ObjPos)
plt.scatter(x, y)
display.clear_output(wait=True)
display.display(plt.gcf())
time.sleep(0.1)
#move object in a random direction
def makeMove2(object,xpos,ypos):
#gets a number: 1,2,3 or 4
direction = int(np.random.uniform(1,4))
if (direction == 1):
ypos = ypos+1
if (direction == 2):
ypos = ypos - 1
if (direction == 3):
xpos = xpos+1
if (direction == 4):
xpos = xpos-1
return xpos,ypos
def Simulation2(rows,cols,objects,steps):
ax,ObjPos = setupGrid2(rows,cols,objects)
for i in range(steps):
for j in range (objects):
xpos = ObjPos[j][0]
ypos = ObjPos[j][1]
newxpos,newypos = makeMove2(j,xpos,ypos)
ObjPos[j][0] = newxpos
ObjPos[j][1] = newypos
updateGrid2(ax,ObjPos)
Simulation2(20,20,2,20)
It seems you want to update the scatter, instead of producing a new scatter for each frame. That would be shown in this question. Of course you can still use display when running this in jupyter instead of the shown solutions with ion or FuncAnimation.
Leaving the code from the question mostly intact this might look as follows.
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import time
import pylab as pl
from IPython import display
def setupGrid2(norows,nocols,noobjects):
#each object needs current grid position (x and y coordinate)
objects = np.zeros(noobjects)
ObjectPos = np.zeros(shape=(noobjects,2))
#put objects randomly on grid
for i in range (noobjects):
ObjectPos[i,0] = np.random.uniform(0,norows)
ObjectPos[i,1] = np.random.uniform(0,nocols)
#plot objects on grid
fig = plt.figure(1,figsize=(15,5))
ax = fig.add_subplot(1,1,1)
ax.axis([0,nocols+1,0,norows+1])
x,y = zip(*ObjectPos)
scatter = ax.scatter(x, y,c="b", label='Initial positions')
ax.grid()
return ax,scatter,ObjectPos
def updateGrid2(ax,sc,ObjPos):
sc.set_offsets(ObjPos)
display.clear_output(wait=True)
display.display(plt.gcf())
time.sleep(0.1)
#move object in a random direction
def makeMove2(object,xpos,ypos):
#gets a number: 1,2,3 or 4
direction = int(np.random.uniform(1,4))
if (direction == 1):
ypos = ypos+1
if (direction == 2):
ypos = ypos - 1
if (direction == 3):
xpos = xpos+1
if (direction == 4):
xpos = xpos-1
return xpos,ypos
def Simulation2(rows,cols,objects,steps):
ax,scatter,ObjPos = setupGrid2(rows,cols,objects)
for i in range(steps):
for j in range (objects):
xpos = ObjPos[j,0]
ypos = ObjPos[j,1]
newxpos,newypos = makeMove2(j,xpos,ypos)
ObjPos[j,0] = newxpos
ObjPos[j,1] = newypos
updateGrid2(ax,scatter,ObjPos)
Simulation2(20,20,3,20)

Categories