This class plots a curve. However, the inputs are currently set in main(). I'd like to set them as user-driven from mouse interaction. Some of this is possible and in the Matplotlib docs (see referenced sites below) but it's still not really setting it up to be a 'click and plot'. So, ideally the user would click a button to set the P and then whatever point (on the curve, has to be on the curve) they clicked next would be the new P. Same with Q. I'm sure this is a very simple question for anyone who's used Matplotlib but I'm teaching myself it right now, but it would probably take an entry-level dev just a few minutes to do something that I'm getting nowhere with.
Code:
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid.axislines import SubplotZero
from math import sqrt
class ECC123(object):
def __init__(self,a,b,px,qx,qy):
self.a = a
self.b = b
self.pxlam = px
self.qxlam = qx
self.invertQy = qy
self.fig = plt.figure(1)
self.ax = SubplotZero(self.fig, 111)
def drawAxis(self):
#fig = plt.figure(1)
#ax = SubplotZero(fig, 111)
self.fig.add_subplot(self.ax)
for direction in ["xzero", "yzero"]:
self.ax.axis[direction].set_axisline_style("->")
self.ax.axis[direction].set_visible(True)
def plotGraph(self):
self.drawAxis()
y, x = np.ogrid[-10:10:100j, -10:10:100j] # range grid [from : to : how_many_points]
xlist = x.ravel(); ylist = y.ravel()
plt.contour(xlist, ylist, self.elliptic_curve(x,y), [0])
pylam = self.ecclambda(self.pxlam,self.a,self.b) # calculate P from pxlam
qylam = self.ecclambda(self.qxlam,self.a,self.b) # calculate Q from qxlam
if self.invertQy == 1: qylam = -qylam # optional, inverts qy to negative on the plot
plt.plot([self.pxlam,self.qxlam], [pylam,qylam], color = "c", linewidth=1)
plt.plot([self.pxlam], [pylam], "mo"); plt.plot([self.qxlam], [qylam], "mo")
plt.text(self.pxlam-0.25,pylam+0.5, '$P$'); plt.text(self.qxlam-0.25,self.qxlam+0.5, '$Q$')
s = (pylam - qylam)/(self.pxlam - self.qxlam) # calculate s slope
xr = s**2 - self.pxlam - self.qxlam # x-value of R
yr = pylam + s*(xr - self.pxlam) # y-value of -R; -y is R (inverted across x-axis)
plt.plot([xr],[yr],"mo")
plt.plot([xr],[-yr],"co")
plt.plot([self.qxlam,xr], [qylam,yr], color = "c", linewidth=1)
plt.plot([xr,xr], [yr,-yr], "x--")
plt.text(xr+0.25,yr, '$-R$'); plt.text(xr+0.25,-yr, '$R$')
plt.grid(True)
plt.show()
I've been going over the docs in Matplotlib, the scipy cookbook, and related questions here on SO and still not seeing exactly how to do this:
http://matplotlib.org/users/event_handling.html
http://matplotlib.org/1.3.1/api/widgets_api.html#matplotlib.widgets.Button.on_clicked
Cursors for data selection in matplotlib
How can I create a frontend for matplotlib?
http://wiki.scipy.org/Cookbook/Matplotlib
So far, I'm getting little red x's all over when I click and they don't even fall within the curve.
I modified your code a little, so that you can set location of P & Q by left & right click, I didn't accomplish all the graph data updates, the rest is left for you:
from mpl_toolkits.axes_grid.axislines import SubplotZero
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt
class ECC(object):
"""
class to implement elliptic curve and find P+Q=R on the plot
"""
def __init__(self,a,b,px,qx,qy):
"""
initialize input variables
"""
self.a = a
self.b = b
self.pxlam = px
self.qxlam = qx
self.invertQy = qy
self.fig = plt.figure(1)
self.ax = SubplotZero(self.fig, 111)
def drawAxis(self):
"""
draw main x,y axis
"""
#fig = plt.figure(1)
#ax = SubplotZero(fig, 111)
self.fig.add_subplot(self.ax)
for direction in ["xzero", "yzero"]:
self.ax.axis[direction].set_axisline_style("->")
self.ax.axis[direction].set_visible(True)
def ecclambda(self,xl,a,b):
"""
returns points elliptic curve for P and Q
y**2 = x**3 + a*x + b
"""
return sqrt(xl**3 + a*xl + b)
def elliptic_curve(self,x,y):
"""
takes in x,y as set of points, returns the elliptic curve
y**2 = x**3 + a*x + b
"""
return pow(y, 2) - pow(x, 3) - x * self.a - self.b
def onclick(self, event):
x = event.xdata
if event.button == 1:
self.pxlam = x
if event.button == 3:
self.qxlam = x
self.update()
def update(self):
pylam = self.ecclambda(self.pxlam,self.a,self.b) # calculate P from pxlam
qylam = self.ecclambda(self.qxlam,self.a,self.b) # calculate Q from qxlam
self.p.set_data([self.pxlam], [pylam])
self.q.set_data([self.qxlam], [qylam])
self.pt.set_x(self.pxlam-0.25)
self.pt.set_y(pylam+0.5)
self.qt.set_x(self.qxlam-0.25)
self.qt.set_y(qylam+0.5)
plt.gcf().canvas.draw()
def plotGraph(self):
"""
main plotting of elliptic curve and points/line for P+Q=R
P+Q=R --->>> -R is plotted (xr,yr), R is plotted (xr, -yr)
conditional with invertQy allows inversion of Q across x-axis; set option in main()
"""
self.drawAxis()
y, x = np.ogrid[-10:10:100j, -10:10:100j] # range grid [from : to : how_many_points]
xlist = x.ravel(); ylist = y.ravel()
plt.contour(xlist, ylist, self.elliptic_curve(x,y), [0])
pylam = self.ecclambda(self.pxlam,self.a,self.b) # calculate P from pxlam
qylam = self.ecclambda(self.qxlam,self.a,self.b) # calculate Q from qxlam
if self.invertQy == 1: qylam = -qylam # optional, inverts qy to negative on the plot
plt.plot([self.pxlam,self.qxlam], [pylam,qylam], color = "c", linewidth=1)
self.p = plt.plot([self.pxlam], [pylam], "mo")[0]
self.q = plt.plot([self.qxlam], [qylam], "mo")[0]
self.pt = plt.text(self.pxlam-0.25,pylam+0.5, '$P$')
self.qt = plt.text(self.qxlam-0.25,self.qxlam+0.5, '$Q$')
s = (pylam - qylam)/(self.pxlam - self.qxlam) # calculate s slope
xr = s**2 - self.pxlam - self.qxlam # x-value of R
yr = pylam + s*(xr - self.pxlam) # y-value of -R; -y is R (inverted across x-axis)
plt.plot([xr],[yr],"mo")
plt.plot([xr],[-yr],"co")
plt.plot([self.qxlam,xr], [qylam,yr], color = "c", linewidth=1)
plt.plot([xr,xr], [yr,-yr], "x--")
plt.text(xr+0.25,yr, '$-R$'); plt.text(xr+0.25,-yr, '$R$')
plt.text(-9,6,' P: (%s ,%s) \n Q: (%s ,%s) \n R: (%s ,%s) \n a: %s \n b: %s '
%(self.pxlam,pylam,self.qxlam,qylam,xr,-yr,self.a,self.b),
fontsize=10, color = 'blue',bbox=dict(facecolor='tan', alpha=0.5))
plt.title(r"Elliptic Curve Implementation $y^{2} = x^{3} + a*x + b$", fontsize = 16, color = 'b')
self.fig.canvas.mpl_connect('button_press_event', self.onclick)
#[xi,yi] = plt.ginput(0)
##print "ginput ",xi,yi
plt.grid(True)
plt.show()
def main():
a = -2; b = 1; px = -1.55; qx = -0.1
invertQy = 0 # set to 1 if q should be inverted to negative along its y axis
ec = ECC(a,b,px,qx,invertQy)
ec.plotGraph()
if __name__ == '__main__':
main()
Related
I am using scipy for non-linear regression optimalization (least_square method). I am drawing the result to the graph utilizing matplotlib and PyQt5. The problem is that the final graph should be exponential and there should not be any breaks like on this picture my current graph. How can I draw it like exponential curve like this without any breaks? Exponential curve
self.figure = Figure()
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
layout = QtWidgets.QVBoxLayout(self.content_plot)
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
self.ax = self.figure.add_subplot(111)
result = self.results[id]
self.fillResultTable(result)
self.setLabelsForResult(result)
x = np.asarray(result.profitList)
y = np.asarray(result.utilityList)
resList = result.resList // resList contains found points for new curve which should be exponential
self.ax.plot(x, y, "o", label="Initial points")
self.ax.legend(loc='lower right')
self.ax.plot(x, resList, label='Final utility function')
self.ax.legend(loc='lower right')
class LeastSquaresOptimalization:
def __init__(self, profitList, utilityList):
self.profitList = np.asarray(profitList) // list of profits
self.utilityList = np.asanyarray(utilityList) // list of corresponding utilities
def function(self, params, x):
a = params[0]
b = params[1]
c = params[2]
return a * np.exp(-x/b) + c
def residual(self, params, x, y):
return (y - self.function(params, x))**2
def startOptimalization(self, a_start, b_start, c_start):
x0 = np.array([a_start, b_start, c_start])
bnds = ([-np.inf, 0.00000001, -np.inf], [-0.00000001, np.inf, np.inf])
result = least_squares(self.residual, x0, args=(self.profitList, self.utilityList), bounds=bnds)
SSE = self.countSSE(result)
pointList = self.countPoints(result)
return result, SSE, pointList
def countPoints(self, result): // this method is used for resList which contains found points
res = self.function(result.x, self.profitList)
return res
I need to simulate a penalty where the ball shoots in every direction. For this I use solve_ivp and I terminate the integration when the ball crosses the backline. When this happens I want to use the values found when the integration stops to see if the ball at that point is within the dimensions of the goal (and count it as a goal). However, solution.y does not give the required precision that I want. The desired values are within solution.y_events, however, I can't seem to be able to get receive them. I also can't find information about this online. My code:
import numpy as np
from scipy import integrate
from scipy import constants
import matplotlib.pyplot as plt
#### Constants
# Number of simulations
number_of_penalty_shots = 10
# Angle of the shots
theta = np.random.uniform(0, 2.0*np.pi, number_of_penalty_shots)
phi = np.random.uniform(0, np.pi, number_of_penalty_shots)
# Velocity of the ball
v_magnitude = 80
### Starting Position Ball (defined as the penalty stip)
pos_x = 0.0
pos_y = 0.0
pos_z = 0.0
in_position = np.array([pos_x, pos_y, pos_z]) # Inital position in m
def homo_magnetic_field(t, vector):
vx = vector[3] # dx/dt = vx
vy = vector[4] # dy/dt = vy
vz = vector[5] # dz/dt = vz
# ax = -0.05*vector[3] # dvx/dt = ax
# ay = -0.05*vector[4] # dvy/dy = ay
# az = -0.05*vector[5] - constants.g #dvz/dt = az
ax = 0
ay = 0
az = 0
dvectordt = (vx,vy,vz,ax,ay,az)
return(dvectordt)
def goal(t, vector):
return vector[1] - 11
def own_goal(t,vector):
return vector[1] + 100
def ground(t,vector):
return vector[2]
goal.terminal=True
own_goal.terminal=True
def is_it_goal(vector):
if vector.status == 1:
if (vector.y[1][len(vector.y[1])-1] > 0) and (-3.36 < vector.y[0][len(vector.y[1])-1] < 3.36) and (vector.y[2][len(vector.y[1])-1] < 2.44):
print("GOAAAAAAAAAAAAL!")
elif (vector.y[1][len(vector.y[1])-1] < 0) and (-3.36 < vector.y[0][len(vector.y[1])-1] < 3.36) and (vector.y[2][len(vector.y[1])-1] < 2.44):
print("Own goal?! Why?")
else: print("Awwwwh")
else: print("Not even close, lol")
# Integrating
time_range = (0.0, 10**2)
for i in range(number_of_penalty_shots):
v_x = v_magnitude*np.sin(phi[i])*np.cos(theta[i])
v_y = v_magnitude*np.sin(phi[i])*np.sin(theta[i])
v_z = v_magnitude*np.cos(phi[i])
in_velocity = np.array([v_x, v_y, v_z])
initial_point = np.array([in_position, in_velocity])
start_point = initial_point.reshape(6,)
solution = integrate.solve_ivp(homo_magnetic_field , time_range, start_point,events=(goal, own_goal))
is_it_goal(solution)
Here I want to change vector.y[1][len(vector.y[1])-1] into something like vector.y_events...
I have the code below. If you run that program a scatter plot is created. The plot is very messy. I want every point to represent one car. I only want to see the point of the current position of each car in the animation. I am not very good at matplotlib, but how would I do that?
from matplotlib import pyplot as plt
import random
import math
from matplotlib import animation
import numpy as np
roadLength = 100
numFrames = 200
numCars = 60
velocities = []
positions = []
theta = []
r = []
color = []
probability = 0.5
vmax = 1
flowr = []
fig = plt.figure()
ax = fig.add_subplot(111, projection='polar')
ax.axis('off')
for i in range(numCars):
positions.append(i * 2)
theta.append(0)
r.append(1)
color.append(i)
velocities.append(0)
def pos(k):
rand = random.uniform(0,1)
if velocities[k] < vmax:
velocities[k] += 1
if k < numCars-1 and (positions[k+1] - positions[k]) <= velocities[k]:
velocities[k] = positions[k+1] - positions[k] - 1
if k == numCars-1 and (roadLength - (positions[k] - positions[0])) <= velocities[k]:
velocities[k] = roadLength - (positions[k] - positions[0]) - 1
if rand < probability and velocities[k] > 0:
velocities[k] = velocities[k] - 1
positions[k] = positions[k] + velocities[k]
return positions[k]
def animate(frameNr):
for i in range(numCars):
theta[i] = pos(i) * 2 * math.pi / roadLength
flowr.append(velocities[i])
ax.scatter(theta, r, c=color)
return ax.scatter(theta, r, c=color),
def simulate():
anim = animation.FuncAnimation(fig, animate,
frames=numFrames, interval=10, blit=True, repeat=False)
plt.show()
simulate()
Thanks in advance!
Edit:
I fixed so that it became a point plot I am now storing velocity, position and lane in an object for a later problem. My question is:
How do I make the points have different colors?
from matplotlib import pyplot as plt
import random
import math
from matplotlib import animation
import numpy as np
from operator import attrgetter
roadLength = 100
numFrames = 200
nlanes = 1
numCars = 20
posss =[]
theta = []
r = []
color = []
probability = 0.5
vmax = 1
flowr = []
cars=[]
class Car:
def __init__(self, position, velocity, lane):
self.position = position
self.velocity = velocity
self.lane = lane
def pos(car,k):
rand = random.uniform(0,1)
if car[k].velocity < vmax:
car[k].velocity += 1
if k < numCars-1 and (car[k+1].position - car[k].position) <= car[k].velocity:
car[k].velocity = car[k+1].position - car[k].position - 1
if k == numCars-1 and (roadLength - (car[k].position - car[0].position)) <= car[k].velocity:
car[k].velocity = roadLength - (car[k].position - car[0].position) - 1
if rand < probability and car[k].velocity > 0:
car[k].velocity = car[k].velocity - 1
car[k].position = car[k].position + car[k].velocity
return car[k].position
for i in range(numCars):
cars.append(Car(i, 0, 1))
theta.append(0)
r.append(1)
color.append(i)
posss.append(i)
fig = plt.figure()
ax = fig.add_subplot(111)
point, = ax.plot(posss, r, 'o')
ax.set_xlim(-10, 1.2*numFrames)
ax.set_ylim(-2, nlanes + 3)
def animate(frameNr):
sort_cars = sorted(cars, key=attrgetter("position"))
for i in range(numCars):
pos(sort_cars,i)
for k in range(numCars):
theta[k]=cars[k].position
point.set_data(theta, r)
return point,
def simulate():
anim = animation.FuncAnimation(fig, animate,
frames=numFrames, interval=10, blit=True, repeat=False)
plt.show()
simulate()
plot() returns a Line2D object, in which all points have the same color.
If you want your points to have different colors, you should use scatter(). The logic is exactly the same, except you use set_offsets(<2D array>) instead of set_data().
See this question for more details
I would like to fill a polygon using basemap/shapefile data, but only a certain %. For example, in the example below, we fill based on the values, but let's say I wanted to fill a % of the polygon based on these values (code from here):
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
import numpy as np
fig= plt.figure()
ax= fig.add_subplot(111)
m=Basemap(projection='cyl',llcrnrlat=34.5,llcrnrlon=19,
urcrnrlat=42,urcrnrlon=28.5,resolution='h')
m.drawmapboundary(fill_color='aqua')
m.fillcontinents(color='w',lake_color='aqua')
m.drawcoastlines()
m.readshapefile('data/nomoi/nomoi','nomoi')
dict1={14464: 1.16, 14465: 1.35, 14466: 1.28, 14467: 1.69, 14468: 1.81, 14418: 1.38}
colvals = dict1.values()
cmap=plt.cm.RdYlBu
norm=plt.Normalize(min(colvals),max(colvals))
patches = []
for info, shape in zip(m.nomoi_info, m.nomoi):
if info['ID_2'] in list(dict1.keys()):
color=cmap(norm(dict1[info['ID_2']]))
patches.append( Polygon(np.array(shape), True, color=color) )
pc = PatchCollection(patches, match_original=True, edgecolor='k', linewidths=1., zorder=2)
ax.add_collection(pc)
#colorbar
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array(colvals)
fig.colorbar(sm, ax=ax)
plt.show()
Thank you.
import math
from shapely.geometry import Polygon as shpoly
#shapefile of main massachusetts shape
iowpoly = state_shapes['Massachusetts'][32]
def return_xy(coords):
return [np.asarray([i[0] for i in coords]), np.asarray([i[1] for i in coords])]
def return_area(coords):
x, y = return_xy(coords)
return 0.5*np.abs(np.dot(x,np.roll(y,1))-np.dot(y,np.roll(x,1)))
def return_bounding_box(coords):
x, y = return_xy(coords)
return [[min(x), min(y)], [max(x), max(y)]]
def split_x_wise(bbox, weights, split = 2):
lleft = bbox[0]
uright = bbox[1]
dx = abs(uright[0] - lleft[0])
weights = np.cumsum(sorted(weights, reverse=True))
xcoords = [lleft[0]+weights[x-1]*dx for x in range(1, split)]
return xcoords
def generate_splits_by_area(coords, bbox, weights, tolerance = 0.03, div = 100):
xareasplits = {}
weights = np.cumsum(sorted(weights, reverse=True))[:-1]
lleft = bbox[0]
uright = bbox[1]
dx = abs(uright[0] - lleft[0])
xsplit = [lleft[0]+(dx/div)*x for x in range(1, div)]
for w in weights:
xareasplits[str(w)] = None
mainarea = shpoly(coords).area
for i, s in enumerate(xsplit):
poly = []
if i == 0:
continue
for ip, p in enumerate(coords):
if p[0] < s:
poly.append(p)
shpl = shpoly(poly).area
frac = shpl/mainarea
for w in weights:
if abs(w-frac) <= tolerance:
if xareasplits[str(w)] == None:
xareasplits[str(w)] = s
return list(xareasplits.values())
def return_split(coords, weights, split = 2, by_area = False, tolerance = 0.03, div = 100):
polys = {}
for x in range(0, split):
polys[str(x+1)] = {'points':[], 'maxit' : None}
bbox = return_bounding_box(coords)
if not by_area:
xsplit = split_x_wise(bbox, weights, split)
#test = generate_splits_by_area(coords, bbox, weights, tolerance=tolerance, div=div)
else:
xsplit = generate_splits_by_area(coords, bbox, weights, tolerance=tolerance, div=div)
xsplit.append(bbox[0][0])
xsplit.append(bbox[1][0])
xsplit = sorted(xsplit)
#print(xsplit)
#print(test)
for ip, p in enumerate(coords):
for i, splt in enumerate(xsplit):
if i > 0:
if (p[0] > xsplit[i-1]) & (p[0] < splt):
if len(polys[str(i)]['points']) == 0:
polys[str(i)]['points'].append(coords[ip-1])
polys[str(i)]['points'].append(p)
polys[str(i)]['maxit'] = ip
for poly, data in polys.items():
tmaxit = data['maxit']+1
if tmaxit >= len(coords):
data['points'].append(coords[0])
else:
data['points'].append(coords[tmaxit])
return polys
#return [p for p in coords if p[0] > xsplit[0]]
#bboxiowa = return_bounding_box(iowpoly)
splitpoly = return_split(iowpoly, weights = [0.2780539772727273, 0.1953716856060606, 0.19513494318181818, 0.18329782196969696, 0.14814157196969696],by_area = True,split = 5)
for k, v in splitpoly.items():
print (k, len(v['points']))
print (v['maxit'])
test = shpoly(splitpoly["1"]['points'])
test
I managed to write my own code to split and fill shapel polygons from shapefiles. The above code example splits the Massachusetts shapefile into 5 segments, weighted according to weights and by area.
The first 2 parts of the split look like this:
I am trying to build a logistic regression model for a dataset consisting of two parameters
x1 and x2, but instead of analyzing just the two of them, I have added their squares as well - x12, x22 and x1· x2.
At the first glance everything looks fine and the error function is decreasing, but whilist drawing the plot of the decision boundary I have noticed, that after circa 500 iterations something strange happens to it.
Here is an animation of the error function as a function of iterations and a respective plot of the decision boundary:
Now,I interpret the decision boundary as a quadratic function
x2=f(x1), where
the relation between both parameters is given like this:
0.5 = θ0 + θ1x1 + θ2x2 + θ3x12 + θ4x1x2
+ θ5x22
Here is the python code I use to do everything:
#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as plt
from math import log
from matplotlib.animation import FuncAnimation
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
def loadData(filepath):
source=""
try:
f = open(filepath, "r")
source = f.read()
f.close()
except IOError:
print("Error while reading file (" + filepath + ")")
return ""
raw_data = source.split("\n")
raw_data = [x.split(",") for x in raw_data if x !=""]
raw_data = np.matrix(raw_data).astype(float)
return (raw_data[:,:np.size(raw_data,1)-1], raw_data[:,np.size(raw_data, 1)-1:])
def standardize(dataset, skipfirst=True):
means = np.amin(dataset, 0)
deviation = np.std(dataset, 0)
if skipfirst:
dataset[:,1:] -= means[:,1:]
dataset[:,1:] /= deviation[:,1:]
return dataset
else:
dataset -= means
dataset /= deviation
return dataset
def error(X, Y, Theta):
"Calculates error values"
v_sigm = np.vectorize(sigmoid)
h_x = X # Theta
sigmo = v_sigm(h_x)
partial_vect = (Y-1).T # np.log(1-sigmo) - Y.T # np.log(sigmo)
return 1/(2*np.size(Y, axis=0))*np.sum(partial_vect)
def gradientStep(X, Y, Theta, LR):
"Returns new theta Values"
v_sigm = np.vectorize(sigmoid)
h_x = X # Theta
modif = -1*LR/np.size(Y, 0)*(h_x-Y)
sums = np.sum(modif.T # X, axis = 0)
return Theta + sums.T
X, Y = loadData("ex2data1.txt")
#add bias to X
X = np.append(np.ones((np.size(X, 0), 1)), X, axis=1)
added_params = [[x[1]**2, x[1]*x[2], x[2]**2] for x in np.array(X)]
X = np.append(X, np.matrix(added_params), axis=1)
#standardize X
X = standardize(X)
#create vector of parameters
Theta=np.zeros((np.size(X, 1), 1))
iterations = 3000
Theta_vals = []
Error_vals = []
for i in range(0, iterations):
Theta_vals.append(np.asarray(Theta).flatten())
Error_vals.append(error(X, Y, Theta))
Theta = gradientStep(X, Y, Theta, 0.07)
#CALCULATING FINISHES HERE
#plot data:
fig = plt.figure()
def_ax = fig.add_subplot(211)
def_ax.set_xlim(np.amin(X[:,1:2]), np.amax(X[:,1:2]))
def_ax.set_ylim(np.amin(X[:,2:3]), np.amax(X[:,2:3]))
err_ax = fig.add_subplot(212)
err_ax.set_ylim(0, error(X, Y, Theta))
err_ax.set_xlim(0, iterations)
positive_X1 = []
positive_X2 = []
negative_X1 = []
negative_X2 = []
for i in range(0, np.size(Y, 0)):
if(Y[i, 0] == 1):
positive_X1.append(X[i, 1])
positive_X2.append(X[i, 2])
else:
negative_X1.append(X[i, 1])
negative_X2.append(X[i, 2])
err_ax.set_ylim(np.amin(Error_vals), np.amax(Error_vals))
def animation(frame):
global Theta_vals, Error_vals, def_ax, err_ax, positive_X1, positive_X2, negative_X1, negative_X2
def_limX = def_ax.get_xlim()
def_limY = def_ax.get_ylim()
err_limX = err_ax.get_xlim()
err_limY = err_ax.get_ylim()
def_ax.clear()
err_ax.clear()
def_ax.set_xlim(def_limX)
def_ax.set_ylim(def_limY)
err_ax.set_xlim(err_limX)
err_ax.set_ylim(err_limY)
def_ax.scatter(positive_X1, positive_X2, marker="^")
def_ax.scatter(negative_X1, negative_X2, marker="o")
Theta = Theta_vals[frame]
res_x = np.linspace(*def_ax.get_xlim(), num=5)
delta_x = [(Theta[4]*x+Theta[2])**2-4*Theta[5]*(Theta[3]*x**2+Theta[1]*x+Theta[0]-0.5) for x in res_x]
delta_x = [np.sqrt(x) if x >= 0 else 0 for x in delta_x]
minb = [-(Theta[4]*x+Theta[2]) for x in res_x]
res_1 = []
res_2 = []
for i in range(0, len(res_x)):
if Theta[5] == 0:
res_1.append(0)
res_2.append(0)
else:
res_1.append((minb[i]+delta_x[i])/(2*Theta[5]))
res_2.append((minb[i]-+delta_x[i])/(2*Theta[5]))
def_ax.plot(res_x, res_1)
def_ax.plot(res_x, res_2)
err_x = np.linspace(0, frame, frame)
err_y = Error_vals[0:frame]
err_ax.plot(err_x, err_y)
anim = FuncAnimation(fig, animation, frames=iterations, interval=3, repeat_delay=2000)
print(error(X, Y, Theta))
anim.save("anim.mp4")
What could be the reason of such a strange behaviour?