Python Forum
Concatenate array for 3D plotting
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Concatenate array for 3D plotting
#1
hello everyone,

i am trying to plot this : (first image). It's basically a cylinder with two hemisphere : one on the top of the cylinder and one on the bottom.

I did it by plotting cylinder and the two hemispheres separately. For each, I have 3 arrays : one for X data, one for Y data and one for Z data (so I have 9 array in total).

I would like, to create only 3 arrays that contain :
- one with all X arrays together ;
- one with all Y arrays together ;
- one with all Z arrays together ;
- and plot everything to obtain the same figure ;

I tried with np.concatenate() function but I got this : (second image). We can see that there is a small difference between first and second picture.

How to procede ? Thanks for your help ! :)


Here is my code below :
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

long = 20

fig = plt.figure()
ax = plt.axes(projection='3d')

# PLOTTING CYLINDER

theta = np.linspace(0, 2*np.pi, 100)
z = np.linspace(0, long-2, len(theta))

theta_grid_cylindre, z_grid_cylindre = np.meshgrid(theta, z)

x_grid_cylindre = 1*np.cos(theta_grid_cylindre) + 0
y_grid_cylindre = 1*np.sin(theta_grid_cylindre) + 0
z_grid_cylindre = z_grid_cylindre + 1

#PLOTTING FIRST HEMISPHERE

theta_1 = np.linspace(0, np.pi/2, 100)

x, y = np.meshgrid(theta, theta_1)

x_grid_sphere = np.cos(x)*np.sin(y)
y_grid_sphere = np.sin(x)*np.sin(y)
z_grid_sphere = np.cos(y)+long-1

#PLOTTING SECOND HEMISPHERE

theta_2 = np.linspace(0, np.pi/2, 100)

x_bas, y_bas = np.meshgrid(theta, theta_2)

x_grid_sphere_bas = np.cos(x_bas)*np.sin(y_bas)
y_grid_sphere_bas = np.sin(x_bas)*np.sin(y_bas)
z_grid_sphere_bas = -np.cos(y_bas)+1

# TRYING TO CONCATENATE ALL ARRAY
 
test_x = np.concatenate((x_grid_sphere,x_grid_cylindre,x_grid_sphere_bas),axis=1)
test_y = np.concatenate((y_grid_sphere,y_grid_cylindre,y_grid_sphere_bas),axis=1)
test_z = np.concatenate((z_grid_sphere,z_grid_cylindre,z_grid_sphere_bas),axis=1)

# PLOTTING EACH PIECE SEPARATELY

ax.plot_surface(x_grid_sphere, y_grid_sphere,z_grid_sphere, color ="green", alpha=0.5)
ax.plot_surface(x_grid_cylindre, y_grid_cylindre,z_grid_cylindre, color ="green", alpha=0.5)
ax.plot_surface(x_grid_sphere_bas, y_grid_sphere_bas,z_grid_sphere_bas, color ="green", alpha=0.5)

# TRYING TO PLOT ALL IN ONE

ax.plot_surface(test_x,test_y,test_z, color ="green", alpha=0.5)

plt.show()
deanhystad write Mar-20-2024, 03:04 PM:
No BBcode Answer
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.

Attached Files

Thumbnail(s)
       
Reply
#2
I don't think you can do this. You have 3 shapes and you cannot just concatenate the points together to get a surface. The problem you have no way to transition gracefully from one surface to another.

Try joining just the two hemispheres to see what I mean.
import numpy as np
import matplotlib.pyplot as plt

long = 20
fig = plt.figure()
ax = plt.axes(projection='3d')

theta = np.linspace(0, 2*np.pi, 100)

theta_1 = np.linspace(0, np.pi/2, 100)
x, y = np.meshgrid(theta, theta_1)
x_grid_sphere = np.cos(x)*np.sin(y)
y_grid_sphere = np.sin(x)*np.sin(y)
z_grid_sphere = np.cos(y)+long-1

theta_2 = np.linspace(0, np.pi/2, 100)
x_bas, y_bas = np.meshgrid(theta, theta_2)
x_grid_sphere_bas = np.cos(x_bas)*np.sin(y_bas)
y_grid_sphere_bas = np.sin(x_bas)*np.sin(y_bas)
z_grid_sphere_bas = -np.cos(y_bas)+1

test_x = np.concatenate((x_grid_sphere, x_grid_sphere_bas),axis=1)
test_y = np.concatenate((y_grid_sphere, y_grid_sphere_bas),axis=1)
test_z = np.concatenate((z_grid_sphere, z_grid_sphere_bas),axis=1)

ax.plot_surface(test_x,test_y,test_z, color ="green", alpha=0.5)

plt.show()
Now change how the points are concatenated:
test_x = np.concatenate((x_grid_sphere, x_grid_sphere_bas),axis=0)
test_y = np.concatenate((y_grid_sphere, y_grid_sphere_bas),axis=0)
test_z = np.concatenate((z_grid_sphere, z_grid_sphere_bas),axis=0)
A much different plot, but you can see how matplotlib is creating a "transition" surface to go frm one set of points to another.

You can't blame numpy and matplotlib for not being able to plot your "surface". By definition, what you are creating is not a surface at all. At best we could describe it as a piece-wise surface, but I challenge you to define a piece-wise function that will generate points on your surface.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Concatenate str JohnnyCoffee 2 2,950 May-01-2021, 03:58 PM
Last Post: JohnnyCoffee
  Save Numpy Array in Another Numpy Array (not Concatenate!) quest 1 1,862 Nov-06-2020, 01:06 PM
Last Post: quest
  Concatenate two dataframes moralear27 2 1,895 Sep-15-2020, 08:04 AM
Last Post: moralear27
  can only concatenate str (not "int") to str gr3yali3n 6 4,143 May-28-2020, 07:20 AM
Last Post: pyzyx3qwerty
  Concatenate two dictionaries harish 3 2,402 Oct-12-2019, 04:52 PM
Last Post: strngr12

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020