Matplotlib Countour not Connected - contour

As a Python novice and trying to visualize the curve X2*Y + X*Y2 - X4 - Y4 = 0 with Matplotlib:
from matplotlib.pyplot import *
from sympy import *
from numpy import *
delta = 0.025
p = arange(-0.5, 1.5, delta)
q = arange(-0.5, 1.5, delta)
X, Y = meshgrid(p, q)
Z = X**2*Y + X*Y**2 - X**4 - Y**4
fig, ax = subplots()
CS = ax.contour(X, Y, Z, [0], colors ='k')
ax.set_title('x**2*y + x*y**2 - x**4 - y**4')
show()
the result is that the plot is not connected, whereas mathematically, it should be so. How can the level set be connected?

It's a year later, but for future reference: You just have to choose a smaller stepsize delta. With your delta = 0.025 your get the disconnected picture:
With delta = 0.001 you get a more accurate connected picture:

Related

Algorithm for a simple circular orbit in 3D [duplicate]

I want to draw a circle with a specified angle of inclination in 3D space using Python. Similar to the image below:
Image
I can already draw circles in 2D. I modified my program by referring to the link below:
Masking a 3D numpy array with a tilted disc
import numpy as np
import matplotlib.pyplot as plt
r = 5.0
a, b, c = (0.0, 0.0, 0.0)
angle = np.pi / 6 # "tilt" of the circle
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_xlim(-10,10)
ax.set_ylim(-10,10)
ax.set_zlim(-10,10)
phirange = np.linspace(0, 2 * np.pi, 300) #to make a full circle
x = a + r * np.cos(phirange)
y = b + r * np.sin(phirange)
z= c
ax.plot(x, y, z )
plt.show()
Now I can draw the circle in 3D space, but I can't get the circle to tilt at the angle I want.
I tried to modify the code in the Z part, the circle can be tilted, but not the result I want.
z = c + r * np.cos(phirange) * np.sin(angle)
Result image:
Do the X and Y parts also need to be modified? What should I do?
update: the circle tilt with other axis
Let i = (1, 0, 0), j = (0, 1, 0). Those are the direction vectors of the x-axis and y-axis, respectively. Those two vectors form an orthonormal basis of the horizontal plane. Here "orthonormal" means the two vectors are orthogonal and both have length 1.
A circle on the horizontal plane with centre C and radius r consists in all points that can be written as C + r * (cos(theta) * i + sin(theta) * j), for all values of theta in range [0, 2 pi]. Note that this works with i and j, but it would have worked equally with any other orthonormal basis of the horizontal plane.
A circle in any other plane can be described exactly the same way, by replacing i and j with two vectors that form an orthonormal basis of that plane.
According to your image, the "tilted plane at angle tilt" has the following orthonormal basis:
a = (cos(tilt), 0, sin(tilt))
b = (0, 1, 0)
You can check that these are two vectors in your plane, that they are orthogonal and that they both have norm 1. Thus they are indeed an orthonormal basis of your plane.
Therefore a circle in your plane, with centre C and radius r, can be described as all the points C + r * (cos(theta) * a + sin(theta) * b), where theta is in range [0, 2 pi].
In terms of x,y,z, this translates into the following system of three parametric equations:
x = x_C + r * cos(theta) * x_a + r * sin(theta) * x_b
y = y_C + r * cos(theta) * y_a + r * sin(theta) * y_b
z = z_C + r * cos(theta) * z_a + r * sin(theta) * z_b
This simplifies a lot, because x_b, y_a, z_b are all equal to 0:
x = x_C + r * cos(theta) * x_a # + sin(theta) * x_b, but x_b == 0
y = y_C + r * sin(theta) * y_b # + cos(theta) * y_a, but y_a == 0
z = z_C + r * cos(theta) * z_a # + sin(theta) * z_b, but z_b == 0
Replacing x_a, y_b and z_a by their values:
x = x_C + r * cos(tilt) * cos(theta)
y = y_C + r * sin(theta)
z = z_C + r * sin(tilt) * cos(theta)
In python:
import numpy as np
import matplotlib.pyplot as plt
# parameters of circle
r = 5.0 # radius
x_C, y_C, z_C = (0.0, 0.0, 0.0) # centre
tilt = np.pi / 6 # tilt of plane around y-axis
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_xlim(-10,10)
ax.set_ylim(-10,10)
ax.set_zlim(-10,10)
theta = np.linspace(0, 2 * np.pi, 300) #to make a full circle
x = x_C + r * np.cos(tilt) * np.cos(theta)
y = y_C + r * np.sin(theta)
z = z_C + r * np.sin(tilt) * np.cos(theta)
ax.plot(x, y, z )
plt.show()

Bayesian calibration for ode system

I tried to use the 'pymc3' package in Python to calibrate a first-order ODE system in a Bayesian way.
I started with a toy ODE system first. It is dy1/dt = y2; dy2/dt = -b* y2 - c*sin(y1). b and c are the parameters I want to calibrate.
Firstly, I generated some outputs for y1 and y2 from t[0,10] by setting parameters b = 0.25 and c = 0.5 with normally distributed noise~N(0,0.7^2). Then, I calibrated the ODE system by setting prior distributions for b~N(0,1) and c~N(0,9) and sigma~HalfNormal
But it gave the errors: (1) TypeError: float() argument must be a string or a number, not 'TensorVariable'(2)ValueError: setting an array element with a sequence.
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy.integrate import ode
import pymc3 as pm
def pend(y, t, b, c):
theta, omega = y
dydt = [omega, -b*omega - c*np.sin(theta)]
return dydt
true_b = 0.25
true_c = 5.0
y0 = [np.pi - 0.1, 0.0]
t = np.linspace(0, 10, 101)
sol = odeint(pend, y0, t, args=(true_b, true_c))
true_sigma = 0.7
noise = np.random.randn(101,2)*true_sigma
Y_obs = sol+noise
pend_model = pm.Model()
with pend_model:
# Priors for unknown model parameters
b = pm.Normal('b', mu=0, sd=1)
c = pm.Normal('c', mu=7, sd=3)
sigma = pm.HalfNormal('sigma', sd=1)
# Expected value of outcome
mu = odeint(pend, y0, t, args=(b, c))
# Likelihood (sampling distribution) of observations
Y = pm.Normal('Y_obs', mu=mu, sd=sigma, observed=Y_obs)
trace = pm.sample(draws=5000, tune=500, chains=1)

Simulation of Lorenz System crashes

I only just started exploring Gekko and tried simulating the Lorenz ODE system.
Unfortunately, I get an error ("no solution found") for a simple std case the runs fine using scipy.
The problem solves fine if I only integrate up to say time=0.5 instead of 1.0
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
m = GEKKO()
m.time = np.arange(0.0, 1.0, 0.01)
sigma = 10.; rho = 28.0; beta = 8./3.
x = m.Var(value=10); y = m.Var(value=10); z = m.Var(value=10)
t = m.Param(value=m.time)
m.Equation(x.dt()== sigma*(y - x))
m.Equation(y.dt()== x*(rho -z) - y)
m.Equation(z.dt()== x*y - beta*z)
m.options.IMODE = 4
m.options.nodes = 4
m.solve(disp=False)
plt.plot(x.value, y.value)
plt.show()
Sequential simulation m.options.IMODE=7 solves successfully. The simultaneous simulation is a larger problem (1782 Variables/Equations vs. 18 Variables/Equations). It also solves successfully if you reduce m.options.NODES=3 (1188 Variables) or increase the maximum iterations m.options.MAX_ITER=300. It failed previously because it needed 267 iterations to find the solution and the maximum iteration limit for IPOPT is 200 by default.
from gekko import GEKKO
import numpy as np
import matplotlib.pyplot as plt
m = GEKKO()
m.time = np.arange(0.0, 1.0, 0.01)
sigma = 10.; rho = 28.0; beta = 8./3.
x = m.Var(value=10); y = m.Var(value=10); z = m.Var(value=10)
t = m.Param(value=m.time)
m.Equation(x.dt()== sigma*(y - x))
m.Equation(y.dt()== x*(rho -z) - y)
m.Equation(z.dt()== x*y - beta*z)
m.options.IMODE = 7
m.options.nodes = 4
m.solve(disp=True)
plt.plot(x.value, y.value)
plt.show()

Optimization integer programming with covariance matrix

I am trying to do a optimization problem which requires the calculation of a new covariance matrix affected by the variable within the implementation.
I am able to do so with scipy optimization Minimize using numpy.cov within my objective function. However, as I need to have integer constraints, I am not able to think of a solution which tackles my issue with cvxpy, gekko since most of the optimization problem online have a fixed covariance matrix.
Below is my code for scipy:
room_revpar = np.array(df.iloc[:,1:10])
nla = np.array([753.2,1077.6, 1278.6,1463.9,1657.0,1990.6,2404.9,2754.6,3464.72])
min_nla = 270517.16
max_nla = 271270.359995
def objective(x, room_revpar,nla,sign = -1.0):
room_revenue = room_revpar * x
avg_revenue = np.mean(room_revenue, axis = 0)
total_revenue = sum(avg_revenue)
cov_matrix = np.cov(room_revenue.T)
total_nla = np.matmul(x.T, nla)
weights = x * nla / total_nla
portfolio_sd = np.sqrt(np.matmul(np.matmul(weights.T, cov_matrix), weights))
adj_risk = total_revenue / portfolio_sd
return sign * adj_risk
def constraint1(x, nla, min_nla):
total_nla = np.matmul(x.T, nla)
return total_nla - min_nla
def constraint2(x, nla, max_nla):
total_nla = np.matmul(x.T, nla)
return max_nla - total_nla
con1 = {'type': 'ineq', 'fun': constraint1, 'args': (nla, min_nla)}
con2 = {'type': 'ineq', 'fun': constraint2, 'args': (nla, max_nla)}
from scipy.optimize import minimize
x = np.ones(9)
sol = minimize(objective,x0 = x, args = (room_revpar, nla), constraints = (con1,con2), options = {'maxiter': 100000})
Would appreciate if anybody has a solution! Thank you.
The covariance of xi and yi is calculated explicitly with np.cov().
import numpy as np
xi = [2.1,2.5,3.6,4.0]
yi = [8,10,12,14]
print(np.cov(xi,yi))
The function np.cov(xi,yi) returns a 2x2 symmetric matrix
[[cov[xi,xi],cov[xi,yi]],
[cov[xi,yi],cov[yi,yi]]]
[[0.80333333 2.26666667]
[2.26666667 6.66666667]]
Gekko needs a symbolic form of the covariance formula for the gradient-based optimizer. Below is a function cov() that creates the symbolic covariance calculation with Gekko variables.
import numpy as np
from gekko import GEKKO
def cov(m,x,y,ddof=1):
''' Calculate the covariance matrix of x, y
Inputs:
m: Gekko model
x: x vector of equal length to y
y: y vector of equal length to x
[ddof=1]: delta degrees of freedom
Returns:
c: covariance as a Gekko variable
'''
nx = len(x); ny = len(y) # length of x, y
if nx!=ny:
print('Error: mismatch of x and y')
xm = m.sum(x)/nx # mean of x
ym = m.sum(y)/ny # mean of y
c = m.Var() # covariance
m.Equation(c==(m.sum([(x[i]-xm)*(y[i]-ym) \
for i in range(nx)]))/(nx-ddof))
return c
m = GEKKO()
n = 4
x = m.Array(m.Param,n)
y = m.Array(m.Param,n)
xi = [2.1,2.5,3.6,4.0]
yi = [8,10,12,14]
for i in range(n):
x[i].value = xi[i]
y[i].value = yi[i]
c0 = cov(m,x,y,ddof=0)
c1 = cov(m,x,y)
m.solve(disp=False)
print('Covariance (Numpy) population cov: ', np.cov(xi,yi,ddof=0)[0,1])
print('Covariance (Numpy) sample cov: ', np.cov(xi,yi)[0,1])
print('Covariance (Gekko) population cov: ', c0.value[0])
print('Covariance (Gekko) sample cov: ', c1.value[0])
Gekko and Numpy produce the same results for the fixed xi and yi values:
Covariance (Numpy) population cov: 1.7
Covariance (Numpy) sample cov: 2.2666666666666666
Covariance (Gekko) population cov: 1.7
Covariance (Gekko) sample cov: 2.2666666667
Now that the cov() function is verified, you can switch x and y to be calculated integer values such as:
x = m.Array(m.Var,n,lb=0,ub=10,integer=True)
y = m.Array(m.Var,n,lb=0,ub=5,integer=True)
To obtain an integer solution, switch to m.options.SOLVER=1 (APOPT) solver before the m.solve() command.

python2.7-colorbar: how to set color scale tick font?

import matplotlib.pyplot as plt
import numpy as np
from numpy import ma
from matplotlib import ticker, cm
N = 100
x = np.linspace(-3.0,3.0,N) # x value
y = np.linspace(-2.0,2.0,N) # y value
X, Y = np.meshgrid(x,y)
Z1 = np.exp(-(X)**2 - (Y)**2)
Z2 = np.exp(-(X*10)**2 - (Y*10)**2)
z = Z1 + 50 * Z2
z[:5, :5] = -1
z = ma.masked_where(z<=0,z)
fig, ax = plt.subplots()
cs = ax.contourf(X,Y,z,locator=ticker.LogLocator(),cmap=cm.PuBu_r)
cbar = fig.colorbar(cs) # add colorbar
plt.show()
the result is shown as follow:
image 1
question: how to set color scale tick font?
just add cbar.ax.set_yticklabels line of code
import matplotlib.pyplot as plt
import numpy as np
from numpy import ma
from matplotlib import ticker, cm
N = 100
x = np.linspace(-3.0,3.0,N) # x value
y = np.linspace(-2.0,2.0,N) # y value
X, Y = np.meshgrid(x,y)
Z1 = np.exp(-(X)**2 - (Y)**2)
Z2 = np.exp(-(X*10)**2 - (Y*10)**2)
z = Z1 + 50 * Z2
z[:5, :5] = -1
z = ma.masked_where(z<=0,z)
fig, ax = plt.subplots()
cs = ax.contourf(X,Y,z,locator=ticker.LogLocator(),cmap=cm.PuBu_r)
cbar = fig.colorbar(cs) # add colorbar
cbar.ax.set_yticklabels(cbar.values, fontname="Arial Black") #this line has been added, i am setting font as Arial Black
plt.show()
Please modify the values as per your need

Resources