i am trying to make a 3d animation of a solarsystem. It works in 2D but when i try to step it up to 3D i run into an error that i cant fix.
My code :
fig2 = plt.figure(figsize = (30,30))
ax2 = fig2.add_subplot(1,1,1, projection = "3d")
ax2.set_xlabel("x...[AE]")
ax2.set_ylabel("y...[AE]")
ax2.set_zlabel("z...[AE]")
ax2.set_xlim(-10,10)
ax2.set_ylim(-10,10)
ax2.set_zlim(-10,10)
#ax.set_xlim(-np.max(x_path),np.max(x_path))
#ax.set_ylim(-np.max(y_path),np.max(y_path))
#ax.set_zlim(-np.max(x_path),np.max(x_path))
ax2.grid()
for i in range(N):
ax2.plot3D(position[i][0]/AE, position[i][1]/AE ,position[i][2]/AE)
planets = [] # müssen für die simulation punkte erstellen, die dann in der simulation geupdated werden
for i in range(N):
punkt, = ax2.plot(position[i][0][0]/ AE, position[i][1][0] / AE, position[i][2][0] /AE, color = color[i], markersize = 50) # erstellt die punkte an den startpositionen
planets.append(punkt)
def update(frames): # funktion for the animation
for i in range(N):
planets[i].set_data(position[i][0][frames] / AE, position[i][1][frames]/AE)
planets[i].set_3d_properties(position[i][2][frames]/AE)
return planets
animation = mpl.animation.FuncAnimation(fig2, update, interval=1000, frames = t.size)
animation.save("Sonnensystem.mp4", fps=30)
plt.show()
the error:
File "file name", line 1538, in plot
zs = np.broadcast_to(zs, len(xs))
TypeError: object of type 'numpy.float64' has no len()
does someone know whats the couse ?
thanks :)
I am trying to genereate a 3D animation of the solarsystem. It workes fine in 2D but for 3D i get an unknown error that i cant fix
Related
maybe you can help me out with a right comment or hint for my problem.
Pretty easy, I would like to plot a 2D slice vtp file (OpenFOAM) via matplotlib as tricontourf plot.
1.) Creating the vtp slice by Paraview and saving as vtp file works like a charme
2.) Using the runtime vtp file, created by cuttingPlane - libsampling OpenFOAM creates a weird triangle order.
What am I missing?
Best,
def loadVTPFile(filename):
import vtk
from vtk.util.numpy_support import vtk_to_numpy
from vtk.util import numpy_support as npvtk
reader = vtk.vtkXMLPolyDataReader()
reader.SetFileName(filename)
reader.Update()
data = reader.GetOutput()
points = data.GetPoints()
npts = points.GetNumberOfPoints()
x = vtk_to_numpy(points.GetData())
triangles= vtk_to_numpy(data.GetPolys().GetData())
ntri = triangles.size // 4 # number of cells
tri = np.take(triangles,[n for n in range(triangles.size) if n%4 != 0]).reshape(ntri,3)
n_arrays = reader.GetNumberOfPointArrays()
for i in range(n_arrays):
print(reader.GetPointArrayName(i))
X = vtk_to_numpy(points.GetData())
x=X[:,0]
y=X[:,1]
z=X[:,2]
# Define the velocity components U=(u,v,w)
U = vtk_to_numpy(data.GetPointData().GetArray('UMean'))
u = U[:,0]
v = U[:,1]
w = U[:,2]
magU=np.sqrt(u**2+v**2+w**2)
p = vtk_to_numpy(data.GetPointData().GetArray('pMean'))
Ma = vtk_to_numpy(data.GetPointData().GetArray('MaMean'))
rho = vtk_to_numpy(data.GetPointData().GetArray('rhoMean'))
return x,y,z,u,v,w,magU,p,Ma,rho,tri
1st: Paraview vtp slice via matplotlib:
Paraview vtp slice via matplotlib
2nd image OpenFOAM cut via libsampling
2nd image OpenFOAM cut via libsampling
Thanks for your help
OpenFOAM vtp slice export:
cellPoint, triangulated true/false, interpolated true/false and so on...
I need some help with this code.....,
the error is "TypeError: 'NormalizedLandmarkList' object is not iterable mediapipe".
In the 19th line of the code.
import cv2
import mediapipe as mp
import math
mp_drawing = mp.solutions.drawing_utils
mp_hands = mp.solutions.holistic
hands = mp_hands.Holistic(static_image_mode=True, )
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
frame = cv2.flip(frame, 1)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = hands.process(frame)
frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
if results.left_hand_landmarks:
for hand_landmarks in results.left_hand_landmarks:
mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS)
keypoint_pos = []
for i in range(21):
x = hand_landmarks.landmark[i].x * frame.shape[1]
y = hand_landmarks.landmark[i].y * frame.shape[0]
keypoint_pos.append((x, y))
cv2.imshow('MediaPipe Hands', frame)
if cv2.waitKey(1) & 0xFF == 27:
break
cap.release()
To access the iterable hand landmarks, we need to do the following.
for hand_landmarks in results.left_hand_landmarks.landmark
Also, make sure to set static_image_mode to False for videos as it has related frames. You can check out this GitHub issue as well.
I am looking to plot a textbox on a figure displaying the 5-Day NHC forecast cone for a tropical cyclone, in this case Hurricane Dorian. I have the four shapefiles (track line, cone, points, and watches/warnings). On the figure I want to display the following from the first row of points_gdf (yellow circles in the image; the two commented out lines near the bottom of the code is what I tried initially):
Latest Tracking Information: (regular string; below are variables from points_gdf)
LAT LON
MAXWIND
GUST
MSLP
TCSPD
track_line_gdf = geopandas.read_file('nhc/al052019_5day_037/al052019-037_5day_lin.shp')
cone_gdf = geopandas.read_file('nhc/al052019_5day_037/al052019-037_5day_pgn.shp')
points_gdf = geopandas.read_file('nhc/al052019_5day_037/al052019-037_5day_pts.shp')
ww_gdf = geopandas.read_file('nhc/al052019_5day_037/al052019-037_ww_wwlin.shp')
fig = plt.figure(figsize=(14,12))
fig.set_facecolor('white')
ax = plt.subplot(1,1,1, projection=map_crs)
ax.set_extent([-88,-70,25,50])
ax.add_geometries(cone_gdf['geometry'], crs=data_crs, facecolor='white',
edgecolor='black', linewidth=0.25, alpha=0.4)
ax.add_geometries(track_line_gdf['geometry'], crs=data_crs, facecolor='none',
edgecolor='black', linewidth=2)
sc = ax.scatter(points_gdf['LON'], points_gdf['LAT'], transform=data_crs,
zorder=10, c=points_gdf['MAXWIND'], cmap='jet')
ww_colors = {'Tropical Storm Watch': 'gold',
'Hurricane Watch': 'pink',
'Tropical Storm Warning': 'tab:blue',
'Hurricane Warning': 'tab:red'}
for ww_type in ww_colors.keys():
ww_subset = ww_gdf[ww_gdf['TCWW']==ww_type]
ax.add_geometries(ww_subset['geometry'], facecolor='none',
edgecolor=ww_colors[ww_type], crs=data_crs,
linewidth=5)
markers = [plt.Line2D([0,0],[0,0],color=color, marker='o', linestyle='') for color in ww_colors.values()]
Name = ww_gdf['STORMNAME'][0]
Storm = ww_gdf['STORMTYPE'][0]
AdvDate = ww_gdf['ADVDATE'][0]
AdvNum = ww_gdf['ADVISNUM'][0]
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
plt.colorbar(sc, label='Wind Speed (mph)')
plt.title(Storm + ' ' + Name + ' - ' + AdvDate + ' Advisory', fontsize=14, fontweight='bold')
plt.legend(markers, ww_colors.keys())
plt.text(0.05, 0.95, 'Testing', transform=ax.transAxes, va='top', bbox=props)
It would help to know either what error you're running into, or what exactly isn't behaving how you want. I can slightly tweak your code to make this:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(14,12))
fig.set_facecolor('white')
ax = plt.subplot(1,1,1, projection=ccrs.LambertConformal())
plt.title('Storm Advisory', fontsize=14, fontweight='bold')
points_gds = pd.DataFrame(dict(GUST=[165.0], LAT=[26.8],
LON=[-78.3], MSLP=[930.2]))
storminfo = f'''Max Wind Gusts: {points_gds.iloc[0]['GUST']:.0f} mph
Current Latitude: {points_gds.iloc[0]['LAT']:.1f}
Current Longitude: {points_gds.iloc[0]['LON']:.1f}
Central Pressure: {points_gds.iloc[0]['MSLP']:.2f} mb'''
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
plt.text(0.05, 0.95, 'Testing', transform=ax.transAxes, va='top', bbox=props)
ax.coastlines()
ax.set_extent([-88,-70,25,50])
which produces this image:
To make that work I needed to change round (which is a Python built-in function) to the string 'round'. The text is formatted using f-strings ("formatted string literals"), and enclosed as a triple-quoted string to avoid needing to manually put in the newline ('\n') characters. Python's docs can tell you more about how to control the formatting of individual items.
I have a pan-tilt-zoom camera (changing focal length over time). There is no idea about its base focal length (e.g. focal length in time point 0). However, It is possible to track the change in focal length between frame and another based on some known constraints and assumptions (Doing a SLAM).
If I assume a random focal length (in pixel unit), for example, 1000 pixel. Then, the new focal lengths are tracked frame by frame. Would I get correct results relatively? Would the results (focal lengths) in each frame be correct up to scale to the ground truth focal length?
For pan and tilt, assuming 0 at start would be valid. Although it is not correct, The estimated values of new tili-pan will be correct up to an offset. However, I suspect the estimated focal length will not be even correct up to scale or offset.. Is it correct or not?
For a quick short answer - if pan-tilt-zoom camera is approximated as a thin lens, then this is the relation between distance (z) and focal length (f):
This is just an approximation. Not fully correct. For more precise calculations, see the camera matrix. Focal length is an intrinsic parameter in the camera matrix. Even if not known, it can be calculated using some camera calibration method such as DLT, Zhang's Method and RANSAC. Once you have the camera matrix, focal length is just a small part of it. You get many more useful things along with it.
OpenCV has an inbuilt implementation of Zhang's method. (Look at this documentation for explanations, but code is old and unusable. New up-to-date code below.) You need to take some pictures of a chess board through your camera. Here is some helper code:
import cv2
from matplotlib import pyplot as plt
import numpy as np
from glob import glob
from scipy import linalg
x,y = np.meshgrid(range(6),range(8))
world_points=np.hstack((x.reshape(48,1),y.reshape(48,1),np.zeros((48,1)))).astype(np.float32)
_3d_points=[]
_2d_points=[]
img_paths=glob('./*.JPG') #get paths of all checkerboard images
for path in img_paths:
im=cv2.imread(path)
ret, corners = cv2.findChessboardCorners(im, (6,8))
if ret: #add points only if checkerboard was correctly detected:
_2d_points.append(corners) #append current 2D points
_3d_points.append(world_points) #3D points are always the same
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(_3d_points, _2d_points, (im.shape[1],im.shape[0]), None, None)
print ("Ret:\n",ret)
print ("Mtx:\n",mtx)
print ("Dist:\n",dist)
You might want Undistortion: Correcting for Radial Distortion
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6*8,3), np.float32)
objp[:,:2] = np.mgrid[0:6,0:8].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
for fname in img_paths:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (6,8),None)
# If found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners)
if 'IMG_5456.JPG' in fname:
plt.figure(figsize=(20,10))
img_vis=img.copy()
cv2.drawChessboardCorners(img_vis, (6,8), corners, ret)
plt.imshow(img_vis)
plt.show()
#Calibration
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
# Reprojection Error
tot_error = 0
for i in range(len(objpoints)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
tot_error += error
print ("Mean Reprojection error: ", tot_error/len(objpoints))
# undistort
mapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
plt.figure(figsize=(20,10))
#cv2.drawChessboardCorners(dst, (6,8), corners, ret)
plt.imshow(dst)
plt.show()
# Reprojection Error
tot_error = 0
for i in range(len(objpoints)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
tot_error += error
print ("Mean Reprojection error: ", tot_error/len(objpoints))
I'm having a hard time with plotting a basemap with Matplotlib and I'm fairly new to it so I was hoping for some help.
I have data of the format:
[ (lat1, lon1, data1),
(lat2, lon2, data2),
(lat3, lon3, data3),
...
(latN, lonN, dataN) ]
And here is some sample data:
(32.0, -128.5, 3.99)
(31.0, -128.0, 3.5027272727272734)
(31.5, -128.0, 3.7383333333333333)
(32.0, -128.0, 3.624)
(32.5, -128.0, 3.913157894736842)
(33.0, -128.0, 4.443333333333334)
Finally, here are some basic statistics about my data that I'm planning to plot:
LAT MIN: 22
LAT MAX: 50
LAT LEN: 1919
LON MIN: -128
LON MAX: -97
LON LEN: 1919
DATA MIN: 0
DATA MAX: 12
DATA LEN: 1919
I need to contour plot on a basemap of the continental United States. I can't, for the life of me, seem to figure out how to setup the data for plotting.
I read that the X-Axis (LATS) needs to be a np.array, and Y-Axis (LONS) needs to be an np.array and that Z (DATA) needs to be a MxN matrix where M = len(LATS) and N = len(LONS). So to me, I see Z as a diagonal matrix where the diagonal contains the data on the diagonal is the values found in DATA corresponding to the index of LATS and LONS.
Here is my code:
def show_map(self, a):
a = sorted(a, key = lambda entry: entry[0]) # sort by latitude
a = sorted(a, key = lambda entry: entry[1]) # then sort by longitude
lats = [ x[0] for x in a ]
lons = [ x[1] for x in a ]
data = [ x[2] for x in a ]
lat_min = min(lats)
lat_max = max(lats)
lon_min = min(lons)
lon_max = max(lons)
data_min = min(data)
data_max = max(data)
x = np.array(lats)
y = np.array(lons)
z = np.diag(data)
m = Basemap(
projection = 'merc',
llcrnrlat=lat_min, urcrnrlat=lat_max,
llcrnrlon=lon_min, urcrnrlon=lon_max,
rsphere=6371200., resolution='l', area_thresh=10000
lat_ts = 20, resolution = 'c'
)
fig = plt.figure()
plt.subplot(211)
ax = plt.gca()
# draw parallels
delat = 10.0
parallels = np.arange(0., 90, delat)
m.drawparallels(parallels, labels=[1,0,0,0], fontsize=10)
# draw meridians
delon = 10.
meridians = np.arange(180.,360.,delon)
m.drawmeridians(meridians,labels=[0,0,0,1],fontsize=10)
# draw map features
m.drawcoastlines(linewidth = 0.50)
m.drawcountries(linewidth = 0.50)
m.drawstates(linewidth = 0.25)
ny = z.shape[0]; nx = z.shape[1] # make grid
lo, la = m.makegrid(nx, ny)
X, Y = m(lo, la)
clevs = [0,1,2.5,5,7.5,10,15,20,30,40,50,70,100,150,200,250,300,400,500,600,750]
cs = m.contour(X, Y, z, clevs)
plt.show()
The plot I get, however, is this: http://imgur.com/li1Wg. I need something to this effect: http://matplotlib.org/basemap/_images/plotprecip.png
Can someone point out what I'm doing wrong and help me plot this? Thank You.
Thanks
I figured out how to do it. This is the code that I finally wrote, and I think this can help other users. If there is a better way of doing this, please state it, since I'm new to Matplotlib.
https://gist.github.com/3789221
Your linked gist is a solution but still wrong in another place.
In your question and in your linked gist you switched x and y coordinates with lon and lat.
x represents lon
y represents lat
Therefore you still get wrong results with your linked gist.
why are you writing:
z = np.diag(data)
From the documentation, numpy.diag(v, k=0) extracts a diagonal or construct a diagonal array.
That should be why you only get a "diagonal area" of values...