My data has Nan values but when I generate a plot the Nan values are considered as min values. I want those values are not shown on the plot.
from matplotlib import pyplot as plt
from matplotlib.tri import Triangulation
import numpy as np
M, N = 11, 1
valuesN = np.array([ np.nan, np.nan, 0.03572389, 0.884389, 0.5, 0.912367,
0.898027, 0.35744717, 0.42150131, np.nan, np.nan ])
valuesE = np.array([ np.nan, np.nan, 0.03572389, 0.02884389, 0.2, 0.312367,
0.55898027, 0.45744717, 0.62150131, np.nan, np.nan ])
valuesS = np.array([ np.nan, np.nan, 0.63572389, 0.02884389, 0.1, 0.14512367,
0.998027, 0.45744717, 0.62150131, np.nan, np.nan ])
valuesW = np.array([ np.nan, np.nan, 0.03572389, 0.02884389, 0., 0.612367,
0.598027, 0.15744717, 0.90131, np.nan, np.nan ])
values = [valuesN, valuesE, valuesS, valuesW]
xv, yv = np.meshgrid(np.arange(-0.5, M), np.arange(-0.5, N))# vertices of the little squares
xc, yc = np.meshgrid(np.arange(0, M), np.arange(0, N)) # centers of the little squares
x = np.concatenate([xv.ravel(), xc.ravel()])
y = np.concatenate([yv.ravel(), yc.ravel()])
cstart = (M + 1) * (N + 1) # indices of the centers
trianglesN = [(i + j * (M + 1), i + 1 + j * (M + 1), cstart + i + j * M) for j in range(N) for i in range(M)]
trianglesE = [(i + 1 + j * (M + 1), i + 1 + (j + 1) * (M + 1), cstart + i + j * M) for j in range(N) for i in range(M)]
trianglesS = [(i + 1 + (j + 1) * (M + 1), i + (j + 1) * (M + 1), cstart + i + j * M) for j in range(N) for i in range(M)]
trianglesW = [(i + (j + 1) * (M + 1), i + j * (M + 1), cstart + i + j * M) for j in range(N) for i in range(M)]
triangul = [Triangulation(x, y, triangles) for triangles in [trianglesN, trianglesE, trianglesS, trianglesW]]
fig, ax = plt.subplots()
imgs = [ax.tripcolor(t, val.ravel(), cmap="jet", vmin=0, vmax=1, ec='white' )
for t, val in zip(triangul, values)]
cbar = fig.colorbar(imgs[0], ax=ax)
ax.invert_yaxis()
ax.margins(x=0, y=0)
ax.set_aspect('equal', 'box') # square cells
plt.tight_layout()
plt.show
I get a plot below, as shown the Nan values are like min values. : ,
Related
import numpy as np
import matplotlib.pyplot as plt
r=20
h=1.7
num_of_steps=100
emp=3
phi = np.linspace(0, 4 * np.pi, num_of_steps)
theta = np.linspace(-np.pi / 4, np.pi / 4, num_of_steps)
x = r * np.cos(phi)
y = r * np.sin(phi) * np.cos(theta) - h * np.sin(theta)
z = r * np.sin(phi) * np.sin(theta) + h * np.cos(theta)
points = [x, y, z]
points = np.transpose(points)
n = len(points)
# Calculate the first and second derivative of the points
dX = np.apply_along_axis(np.gradient, axis=0, arr=points)
ddX = np.apply_along_axis(np.gradient, axis=0, arr=dX)
# Normalize all tangents
f = lambda m: m / np.linalg.norm(m)
T = np.apply_along_axis(f, axis=1, arr=dX)
# Calculate and normalize all binormals
B = np.cross(dX, ddX)
B = np.apply_along_axis(f, axis=1, arr=B)
# Calculate all normals
N = np.cross(B, T)
for t in range(len(theta)):
fig = plt.figure('Parametrinai blynai')
ax = fig.add_subplot(111, projection='3d')
ax.plot(x[1:t], y[1:t], z[1:t], '-r', linewidth=3)
ax.set_xlabel('X', fontweight='bold', fontsize=14)
ax.set_ylabel('Y', fontweight='bold', fontsize=14)
ax.set_zlabel('Z', fontweight='bold', fontsize=14)
ax.set_xlim([-20, 20])
ax.set_ylim([-20, 20])
ax.set_zlim([-10, 10])
plt.title('Parametrinis blynas', fontweight='bold', fontsize=16)
ax.quiver(x[t - 1], y[t - 1], z[t - 1], emp * T[t, 0], emp * T[t, 1], emp * T[t, 2], color='k')#juoda
ax.quiver(x[t - 1], y[t - 1], z[t - 1], emp * B[t, 0], emp * B[t, 1], emp * B[t, 2], color='b')#melyna
ax.quiver(x[t - 1], y[t - 1], z[t - 1], emp * N[t, 0], emp * N[t, 1], emp * N[t, 2], color='g')#zalia
# T, B ir N masyvai yra 100x3 dydio aka 3 dimensijos 100 iteraciju
# tuose masyvuose per 100 iteraciju yra deltaX, deltaY ir deltaZ normavimo konstantos tikslumu yra
# T, B arba N vektoriaus ilgis x, y ir z asyse
# Uncomment either option 1 or option 2
# Option 1
#plt.show()
# Option 2
#pavadinimas = str(t)
#plt.savefig(pavadinimas, dpi=300)
print(T[t]) #vektoriukas, judantis isilgai kartu su projekcijos tasku
print(B[t]) #
print(N[t])
#print("ciklas:" + str(t))
The code above plots a trajectory, defined by the three equations. How do i modify the code to produce a 3D Lissajous figure? For example both angles theta and phi should have frequencies and amplitudes and botha angles should be moving harmonically, i.e. angle theta should start at -pi/4, reach pi/4 and then go backwards to -pi/4 and so on like a pendulum. Is there any way to implement this into the above code or some way to change it?
I have two numpy ndarrays, array1 and array 2, with array1.shape = array2.shape = (n, l, m).
A 3rd ndarray is initialized as array3 = np.nan * np.zeros((n-1, l, m + 1)) and is then computed using the following for loop:
for i in range(m):
array3[:n - i - 1, :, i] = array1[i + 1:, :, i] - array2[:n - i - 1, :, i]
Is there a simple way to vectorize this and avoid the for loop ?
Here is a simple example:
import numpy as np
a = np.ones((6, 4, 4)) * np.arange(1, 5)
b = np.ones((6, 4, 4))
c = np.nan * np.zeros((5, 4, 4))
n = a.shape[0]
m = a.shape[2]
for i in range(m):
c[:n - i - 1, :, i] = a[i + 1:, :, i] - b[:n - i - 1, :, i]
I tried rewriting array a the following way:
a = np.concatenate((a, np.nan * np.zeros((4, 4, 4))), axis=0)
row_idx, column_idx, slice_idx = np.ogrid[:a.shape[0], :a.shape[1], :a.shape[2]]
r = -1.0 * np.arange(1, 5) + a.shape[0]
row_idx = (row_idx - r[np.newaxis, np.newaxis, :]).astype(int)
a = a[row_idx, column_idx, slice_idx]
a = a[:6, :, :]
and then subtract array b directly but it was only marginally faster for arrays of larger size.
I´m an mechanical engineering student and I'm trying to make a shear diagram of a portal frame.
In the code below I want to identify for each equation (4 in total) the maximum value and correspondent position on the plot. How can I do that? Is it possible to mark the location with a "x"?
The equations are vpilar 1, vpilar 2, vasna1 and vasna2.
Code:
import math as mt
import numpy as np
import matplotlib.pyplot as plt
v = 20 #(Vão em metros)
h = 6 #("Altura do pilar em metros:")
ht = 8 #("Altura total metros:")
alfa_rad = mt.atan((int(ht)-int(h))/(int(v)/2))
alfa_deg = alfa_rad*180/mt.pi
lasna = ((v/2) ** 2 + (ht-h) ** 2) ** 0.5
alfa = (mt.atan((int(ht)-int(h))/(int(v)/2)))*180/((mt.pi))
print("Ângulo da vertente:", round(alfa, 1), "º")
h1 = np.arange(0, h+1, 1)
ha1 = np.arange(0, lasna, 0.1)
ha2 = np.arange(0, lasna, 0.1)
hp2 = np.arange(0, h+1, 1)
R = lambda x, y, theta: np.array([
[np.cos(theta), np.sin(theta), x],
[-np.sin(theta), np.cos(theta), y],
[0, 0, 1],
])
Vx = np.array([
[1, 0, 0], [0, -1, 0], [0, 0, 1]
])
Vy = np.array([
[-1, 0, 0], [0, 1, 0], [0, 0, 1]
])
vpilar1 = (1000 * h1 ** 2 + 50)/ 1000
vasna1 = (50 *ha1 ** 2 + 5) / 1000
vasna2 = (100 * ha2 ** 2 + 7) / 1000
vpilar2 = (150 * hp2 ** 2 + 5) / 1000
def draw_line():
x_number_list = [0, 0, (v/2), v, v]
y_number_list = [0, h, ht, h, 0]
plt.plot(x_number_list, y_number_list, linewidth=3)
points1 = np.stack([h1, vpilar1 / max(abs(vpilar1)), np.ones_like(h1)])
points1 = np.matmul(R(0, 0, -np.pi/2), points1)
plt.plot(points1[0, :], points1[1, :], label="Vpilar1")
points2 = np.stack([h1, vpilar2 / max(abs(vpilar2)), np.ones_like(h1)])
points2 = np.matmul(R(v, 0, -np.pi/2), points2)
plt.plot(points2[0, :], points2[1, :], label="Vpilar2")
points3 = np.stack([ha1, vasna1 / max(abs(vasna1)), np.ones_like(ha1)])
points3 = np.matmul(R(0, h, -alfa_rad), points3)
plt.plot(points3[0, :], points3[1, :], label="Vasna1")
points4 = np.stack([ha1, vasna2 / max(abs(vasna2)), np.ones_like(ha1)])
points4 = np.matmul(np.matmul(R(v, h, alfa_rad), Vy), points4)
plt.plot(points4[0, :], points4[1, :], label="Vasna2")
plt.title("Esforço de Corte", fontsize=15)
plt.show()
draw_line()
With np.argmax you find the index of the maximum of an array. Then extract the coordinates of that position, and apply the same transformation matrix you previously applied to the moments. Finally, your mark this new position on the chart:
import math as mt
import numpy as np
import matplotlib.pyplot as plt
v = 20 #(Vão em metros)
h = 6 #("Altura do pilar em metros:")
ht = 8 #("Altura total metros:")
alfa_rad = mt.atan((int(ht)-int(h))/(int(v)/2))
alfa_deg = alfa_rad*180/mt.pi
lasna = ((v/2) ** 2 + (ht-h) ** 2) ** 0.5
alfa = (mt.atan((int(ht)-int(h))/(int(v)/2)))*180/((mt.pi))
print("Ângulo da vertente:", round(alfa, 1), "º")
h1 = np.arange(0, h+1, 1)
ha1 = np.arange(0, lasna, 0.1)
ha2 = np.arange(0, lasna, 0.1)
hp2 = np.arange(0, h+1, 1)
R = lambda x, y, theta: np.array([
[np.cos(theta), np.sin(theta), x],
[-np.sin(theta), np.cos(theta), y],
[0, 0, 1],
])
Vx = np.array([
[1, 0, 0], [0, -1, 0], [0, 0, 1]
])
Vy = np.array([
[-1, 0, 0], [0, 1, 0], [0, 0, 1]
])
vpilar1 = (1000 * h1 ** 2 + 50)/ 1000
vasna1 = (50 *ha1 ** 2 + 5) / 1000
vasna2 = (100 * ha2 ** 2 + 7) / 1000
vpilar2 = (150 * hp2 ** 2 + 5) / 1000
def draw_line():
plt.figure()
x_number_list = [0, 0, (v/2), v, v]
y_number_list = [0, h, ht, h, 0]
plt.plot(x_number_list, y_number_list, linewidth=3)
points1 = np.stack([h1, vpilar1 / max(abs(vpilar1)), np.ones_like(h1)])
points1 = np.matmul(R(0, 0, -np.pi/2), points1)
plt.plot(points1[0, :], points1[1, :], label="Vpilar1")
idx = np.argmax(vpilar1)
max_p = np.array([[h1[idx], (vpilar1 / max(abs(vpilar1)))[idx], 1]]).T
max_p_tranformed = np.matmul(R(0, 0, -np.pi/2), max_p)
plt.scatter(*max_p_tranformed[:-1], marker="x", color="k")
points2 = np.stack([h1, vpilar2 / max(abs(vpilar2)), np.ones_like(h1)])
points2 = np.matmul(R(v, 0, -np.pi/2), points2)
plt.plot(points2[0, :], points2[1, :], label="Vpilar2")
idx = np.argmax(vpilar2)
max_p = np.array([[h1[idx], (vpilar2 / max(abs(vpilar2)))[idx], 1]]).T
max_p_tranformed = np.matmul(R(v, 0, -np.pi/2), max_p)
plt.scatter(*max_p_tranformed[:-1], marker="x", color="k")
points3 = np.stack([ha1, vasna1 / max(abs(vasna1)), np.ones_like(ha1)])
points3 = np.matmul(R(0, h, -alfa_rad), points3)
plt.plot(points3[0, :], points3[1, :], label="Vasna1")
idx = np.argmax(vasna1)
max_p = np.array([[ha1[idx], (vasna1 / max(abs(vasna1)))[idx], 1]]).T
max_p_tranformed = np.matmul(R(0, h, -alfa_rad), max_p)
plt.scatter(*max_p_tranformed[:-1], marker="x", color="k")
points4 = np.stack([ha1, vasna2 / max(abs(vasna2)), np.ones_like(ha1)])
points4 = np.matmul(np.matmul(R(v, h, alfa_rad), Vy), points4)
plt.plot(points4[0, :], points4[1, :], label="Vasna2")
idx = np.argmax(vasna2)
max_p = np.array([[ha1[idx], (vasna2 / max(abs(vasna2)))[idx], 1]]).T
max_p_tranformed = np.matmul(np.matmul(R(v, h, alfa_rad), Vy), max_p)
plt.scatter(*max_p_tranformed[:-1], marker="x", color="k")
plt.title("Esforço de Corte", fontsize=15)
plt.show()
draw_line()
I am implementing threshold regression using SCAD penalty function, SCAD has its own defined derivative, so I also implement the function of SCAD derivative.I pass the derivative to the "optimize"'s jac parameters.
I first used the target function without the SCAD penalty function to give the initial guess, and it can work.
However, when using the penalty function with SCAD to solve the problem, the iterator cannot give correct results, and returns 'Desired error not necessarily achieved due to precision loss.'
What shall i do?
import pandas as pd
import scipy as sc
from scipy import stats as st
import numpy as np
from scipy import optimize as opt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import pyplot as plt
def loss_SCAD(beta_matrix):
M_MSE = np.dot(x, beta_matrix[:tmp_lt])[:, None]
M_c = np.array(beta_matrix[-M:], ndmin=1)
scad = 0
for idx, c in enumerate(M_c):
nor_distri_x = (x[:, 1][:, None] - c) / tmp_h
nor_distri_CDF = st.norm.cdf(nor_distri_x) # 光滑示性函数
M_MSE += np.dot(x, beta_matrix[tmp_lt * (idx + 1):tmp_lt * (idx + 2)])[:, None] * nor_distri_CDF
beta_param = np.sum(np.abs(beta_matrix[tmp_lt * (idx + 1):tmp_lt * (idx + 2)]))
if beta_param > a * tmp_lam:
scad += 0.5 * ((a + 1) * tmp_lam ** 2)
elif beta_param > tmp_lam:
scad += ((a ** 2 - 1) * tmp_lam ** 2 - (beta_param - a * tmp_lam) ** 2) / (2 * (a - 1))
else:
scad += tmp_lam * beta_param
MSE = 0.5 * np.average((y - M_MSE) ** 2) + scad
return MSE
def loss_derivative(beta_matrix):
deriv_list = []
other_M_MSE, nor_distri_CDF = 0, 0
first_M_MSE = y - np.dot(x, beta_matrix[:tmp_lt])[:, None]
M_c = np.array(beta_matrix[-M:], ndmin=1)
for idx, c in enumerate(M_c):
nor_distri_x = (x[:, 1][:, None] - c) / tmp_h
nor_distri_CDF = st.norm.cdf(nor_distri_x) # 光滑示性函数
other_M_MSE += np.dot(x, beta_matrix[tmp_lt * (idx + 1):tmp_lt * (idx + 2)])[:, None] * nor_distri_CDF
square_part = first_M_MSE - other_M_MSE
for idx, beta_param in enumerate(beta_matrix[:tmp_lt]): # 更新梯度:第一段
deriv_list.append(np.average(square_part * -x[:, idx][:, None]))
for idx, c in enumerate(M_c):
beta_param = np.sum(np.abs(beta_matrix[tmp_lt * (idx + 1):tmp_lt * (idx + 2)]))
if beta_param == 0: # 更新梯度:SCAD函数
scad = 0
elif beta_param > tmp_lam:
scad = np.max(((a * tmp_lam - beta_param) / (a - 1), 0))
else:
scad = tmp_lam
for i in range(tmp_lt): # 更新梯度:分段
deriv_list.append(np.average(square_part * -x[:, i][:, None] * nor_distri_CDF) + scad)
for idx, c in enumerate(M_c): # 更新梯度:门槛参数
nor_distri_PDF = st.norm.pdf((tmp_x - c) / tmp_h)
deriv_list.append(np.average(square_part * np.dot(x, beta_matrix[tmp_lt * (idx + 1):tmp_lt * (idx + 2)])[:, None] * nor_distri_PDF / tmp_h))
return np.array(deriv_list)
def loss(beta_matrix):
M_MSE = np.dot(x, beta_matrix[:tmp_lt])[:, None]
M_c = np.array(beta_matrix[-M:], ndmin=1)
for idx, c in enumerate(M_c):
nor_distri_x = (x[:, 1][:, None] - c) / tmp_h
nor_distri_CDF = st.norm.cdf(nor_distri_x) # 光滑示性函数
M_MSE += np.dot(x, beta_matrix[tmp_lt * (idx + 1):tmp_lt * (idx + 2)])[:, None] * nor_distri_CDF
MSE = 0.5 * np.average((y - M_MSE) ** 2)
return MSE
np.random.seed(1171359)
a = 3.7
tmp_x = np.random.normal(loc=0, scale=2, size=(400, 1))
tmp_beta = [2, -2, 5, 2, 9, 7]
tmp_c = [-np.sqrt(2), np.sqrt(2)]
M = np.shape(tmp_c)[0]
x1, x2, x3 = tmp_x[tmp_x < tmp_c[0]], tmp_x[(tmp_x >= tmp_c[0]) & (tmp_x < tmp_c[1])], tmp_x[tmp_x >= tmp_c[1]]
y1, y2, y3 = tmp_beta[0] + tmp_beta[1] * x1, tmp_beta[2] + tmp_beta[3] * x2, tmp_beta[4] + tmp_beta[5] * x3
x = np.reshape(np.concatenate((x1, x2, x3)), (-1, 1))
y = np.reshape(np.concatenate((y1, y2, y3)) + np.random.randn(400), (-1, 1))
x = np.concatenate((np.ones_like(x), x), axis=1)
tmp_lt = x.shape[1]
tmp_h = np.log(400) / 400 * tmp_x.std(ddof=1)
tmp_lam = 0.5
tmp_res = opt.minimize(fun=loss, x0=np.append(np.ones(7), 2))
tmp_result = opt.minimize(fun=loss_SCAD, x0=tmp_res.x, jac=loss_derivative)
# print(tmp_result.x, tmp_res.x, sep='\n')
k = tmp_result.x[:-2].reshape((2, -1), order='F')
y_hat_1 = np.dot(x[x[:, 1] < tmp_result.x[-2]], k[:, 0].reshape((-1, 1)))
y_hat_2 = np.dot(x[(x[:, 1] >= tmp_result.x[-2]) & (x[:, 1] < tmp_result.x[-1])], k[:, 0].reshape((-1, 1)) + k[:, 1].reshape((-1, 1)))
y_hat_3 = np.dot(x[x[:, 1] >= tmp_result.x[-1]], k[:, 0].reshape((-1, 1)) + k[:, 1].reshape((-1, 1)) + k[:, 2].reshape((-1, 1)))
print(k, tmp_result.fun, tmp_result, sep='\n')
fig = plt.figure(111, figsize=(6, 6))
plt.plot(x[:, 1][x[:, 1] < tmp_result.x[-2]], y_hat_1, c='orange', alpha=0.6, linewidth=4)
plt.plot(x[:, 1][(x[:, 1] >= tmp_result.x[-2]) & (x[:, 1] < tmp_result.x[-1])], y_hat_2, c='blue', alpha=0.6, linewidth=4)
plt.plot(x[:, 1][x[:, 1] >= tmp_result.x[-1]], y_hat_3, c='green', alpha=0.6, linewidth=4)
plt.plot(x1, y1, c='black', alpha=0.6, linewidth=4)
plt.plot(x2, y2, c='black', alpha=0.6, linewidth=4)
plt.plot(x3, y3, c='black', alpha=0.6, linewidth=4)
plt.scatter(x[:, 1], y, s=12, alpha=0.5, c='gray')
plt.axis([tmp_x.min() * 1.05, tmp_x.max() * 1.05, y.min() * 1.05, y.max() * 1.05])
plt.show()
fun: 1.6869804934437402
hess_inv: array([[1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 1]])
jac: array([ 1.98384534e-07, -2.81814249e-07, -1.51727486e-08, -2.17460279e-08,
-1.51727486e-08, -2.17460279e-08, -1.15503569e+00, -6.99892939e-01])
message: 'Desired error not necessarily achieved due to precision loss.'
nfev: 84
nit: 0
njev: 72
status: 2
success: False
x: array([ 1.93751362, -2.04506983, 3.09129046, 4.13404934, 4.32073797,
4.87646363, -1.391239 , 1.4099789 ])
I have a 3 sets of meshgrid coordinates of a 3D cylinder:
X, Y, Z = [p1[i] + v[i] * t1 + r * np.sin(theta2) * n1[i] + r * np.cos(theta2) * n2[i] for i in [0, 1, 2]]
here the definition of p1, v, t1, r and theta2:
r = 3
start = [30, 45, 60]
end = [40, 58, 70]
p1 = np.array(start)
p2 = np.array(end)
v = p2 - p1
mag = scipy.linalg.norm(v)
v = v / mag
not_v = np.array([1, 0, 0])
if (v == not_v).all():
not_v = np.array([0, 1, 0])
n1 = np.cross(v, not_v)
n1 /= scipy.linalg.norm(n1)
n2 = np.cross(v, n1)
t = np.linspace(0, mag, 100)
theta = np.linspace(0, 2 * np.pi, 100)
t1, theta2 = np.meshgrid(t, theta)
I don't know if I didn't understand correctly how numpy.meshgrid works, but I'm looking for a way to get the (x,y,z) points of the polyhedron.