matplotlib: Continuously overwriting - python

I would like to plot my intermediate results and want to see how is the algorithm progressing. I have posted a demo code too. Lets say my algorithm goes for 20 epochs and I want to plot the result of every epoch in a same file. I tried with following demo code. But I can not see any plot on a.png.
Could someone help me how could I do it?
import matplotlib.pylab as plt
import numpy as np
for i in range(20):
y = np.random.random()
plt.plot(i, y)
plt.savefig('a.png')

You have to provide the whole history in your variables e.g. as a list:
import matplotlib.pylab as plt
import numpy as np
# creates two lists with the same length
x = range(20)
y = [0] * 20
for i in x:
y.insert(i, np.random.random())
plt.plot(x, y)
plt.savefig('plot_%d.png' % i)

Related

Point deviding by line with matplotlib

I made 30 random points using np.random.uniform.
And i want these points to be divided by random line like the picture below.
Could you give me some codes or advice??
Making points is easy but dividing is difficult ..
Code is like this
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import random
import math
m=np.random.uniform(-10,10,30)
n=np.random.uniform(-10,10,30)
a=random.randrange(-5,5)
b=random.randrange(-10,10)
x= np.array(range(-10,20))
y=a*x+b
plt.plot(x,y)
plt.scatter(m,n)
plt.xlim(-10,10)
plt.ylim(-10,10)
plt.show()
enter image description here
I want to devide points by the line like this
enter image description here
I feel like using for loop is possible but I don't know how. Could you give me some advice??
I think you can use the filter function to divide the points into two parts.
The code is Here.
import numpy as np
import matplotlib.pyplot as plt
import random
m=np.random.uniform(-10,10,30)
n=np.random.uniform(-10,10,30)
a=random.randrange(-5,5)
b=random.randrange(-10,10)
x= np.array(range(-10,20))
y=a*x+b
plt.plot(x,y)
# above
result = list(filter(lambda item: item[1] >= a*item[0]+b, zip(m,n)))
xa, ya = list(zip(*result))
plt.scatter(xa,ya,color = "r",marker="*")
# below
result = list(filter(lambda item: item[1] < a*item[0]+b, zip(m,n)))
xb, yb = list(zip(*result))
plt.scatter(xb,yb, marker="^",color="b")
plt.xlim(-10,10)
plt.ylim(-10,10)
plt.show()

How can i have my code print more than one graph at a time?

I am quite new to python so please bear with me.
My code is below:
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
df = pd.read_csv(r"/Users/aaronhuang/Desktop/ffp/exfileCLEAN2.csv", skiprows=[1])
magnitudes = df['Magnitude '].values
times = df['Time '].values
zscores = np.abs(stats.zscore(magnitudes, ddof=1))
outlier_indicies = np.argwhere(zscores > 3).flatten()
print(times[outlier_indicies])
window = 10
num = 1
x = times[outlier_indicies[num]-window:outlier_indicies[num]+window+1]
y = magnitudes[outlier_indicies[num]-window:outlier_indicies[num]+window+1]
plt.plot(x, y)
plt.xlabel('Time (units)')
plt.ylabel('Magnitude (units)')
plt.show()
fig = plt.figure()
fig.savefig("/Users/aaronhuang/Downloads")
Is there a way I can print all the graphs separately once?. Deleting num has not worked.
Thank you in advance.
You can put the plots inside a for loop, and repeat as many times as you like, with different variables for each step if needed. Most software will show the plots either in multiple plot windows, or output them in a long strip you can scroll through. If you use Spyder however, they will play back to back, with each plot being a frame.
Also, if you want to print multiple plots, you have to put the plt.show() inside the loop as well, putting it after the loop will show all the values on a single plot.
For example:
import matplotlib.pyplot as plt
x_values = [1,2,3,4,5,6,7]
for x in x_values:
y = x**2
plt.plot(x,y,"o")
plt.axis([0,50, 0,50])
plt.show()

Is there a method to connect a point with previous a point?

I am trying to use plt.scatter to generate multiple points and I want to connect each point with the previous one. For my x-axes I need to use the format time.time() or something that will allow me to draw points each second.
I tried to use plt.plot(), but that will result in changes I don't need.
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import time
ts = time.time()
kraft = 2300
for i in range(10):
ts1 = ts + i
kraft1 = kraft + i
plt.scatter(ts1, kraft1)
plt.show()
I expect to have multiple points connected to the former point.
Thanks for you answers.
The straightforward solution is to use save your values in a list and plot all of them at once using style '-o' which represents a line and a marker. You don't need extra variables ts1 and kraft1 here
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import time
ts = time.time()
kraft = 2300
x, y = [], []
for i in range(10):
x.append(ts + i)
y.append(kraft + i)
plt.plot(x, y, '-o')

Simple plotting of log function in python

I wrote a simple function to plot log in python:
import matplotlib.pyplot as plt
import numpy as np
x = list(range(1, 10000, 1))
y = [-np.log(p/10000) for p in x]
plt.scatter(x, y) # also tried with plt.plot(x, y)
plt.show()
I just want to see how the plot looks.
fn.py:5: RuntimeWarning: divide by zero encountered in log
y = [-np.log(p/10000) for p in x]
I get the above error and on top of that I get a blank plot with even the ranges wrong.
It is strange why there is divide by zero warning, when I am dividing by a number?
How can I correctly plot the function?
Although you have tagged python-3.x, it seems that you are using python-2.x where p/10000 will result in 0 for values of p < 10000 because the division operator / performs integer division in python-2.x. If that is the case, you can explicitly use 10000.0 instead of 10000 to avoid that and get a float division.
Using .0 is not needed in python 3+ because by default it performs float division. Hence, your code works fine in python 3.6.5 though
import matplotlib.pyplot as plt
import numpy as np
x = list(range(1, 10000, 1))
y = [-np.log(p/10000.0) for p in x]
plt.scatter(x, y)
plt.show()
On a different note: You can simply use NumPy's arange to generate x and avoid the list completely and use vectorized operation.
x = np.arange(1, 10000)
y = -np.log(x/10000.0)
Why import numpy and then avoid using it? You could have simply done:
from math import log
import matplotlib.pyplot as plt
x = xrange(1, 10000)
y = [-log(p / 10000.0) for p in x]
plt.scatter(x, y)
plt.show()
If you're going to bring numpy into the picture, think about doing things in a numpy-like fashion:
import matplotlib.pyplot as plt
import numpy as np
f = lambda p: -np.log(p / 10000.0)
x = np.arange(1, 10000)
plt.scatter(x, f(x))
plt.show()

resampled time using scipy.signal.resample

I have a signal that is not sampled equidistant; for further processing it needs to be. I thought that scipy.signal.resample would do it, but I do not understand its behavior.
The signal is in y, corresponding time in x.
The resampled is expected in yy, with all corresponding time in xx. Does anyone know what I do wrong or how to achieve what I need?
This code does not work: xx is not time:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
x = np.array([0,1,2,3,4,5,6,6.5,7,7.5,8,8.5,9])
y = np.cos(-x**2/4.0)
num=50
z=signal.resample(y, num, x, axis=0, window=None)
yy=z[0]
xx=z[1]
plt.plot(x,y)
plt.plot(xx,yy)
plt.show()
Even when you give the x coordinates (which corresponds to the t argument), resample assumes that the sampling is uniform.
Consider using one of the univariate interpolators in scipy.interpolate.
For example, this script:
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
x = np.array([0,1,2,3,4,5,6,6.5,7,7.5,8,8.5,9])
y = np.cos(-x**2/4.0)
f = interpolate.interp1d(x, y)
num = 50
xx = np.linspace(x[0], x[-1], num)
yy = f(xx)
plt.plot(x,y, 'bo-')
plt.plot(xx,yy, 'g.-')
plt.show()
generates this plot:
Check the docstring of interp1d for options to control the interpolation, and also check out the other interpolation classes.

Categories