Setting coordinates for sphere - python

I have a code that produces a sphere. I want to change the coordinates in which the sphere spawns
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from matplotlib import cm
from matplotlib import animation
import pandas as pd
fig = plt.figure(facecolor='black')
ax = plt.axes(projection = "3d")
u = np.linspace(0, 2*np.pi, 100)
v = np.linspace(0, np.pi, 100)
r = 10
ax.set_xlim(0, 60)
ax.set_ylim(0, 60)
ax.set_zlim(0, 60)
x = r * np.outer(np.cos(u), np.sin(v))
y = r * np.outer(np.sin(u), np.sin(v))
z = r * np.outer(np.ones(np.size(u)), np.cos(v))
def init():
ax.plot_surface(x,y,z)
return fig,
def animate(i):
ax.view_init(elev = 20, azim = i*4)
ani = animation. FuncAnimation(fig, animate, init_func = init, frames = 90, interval = 299)
plt.show()
So for instance, I want the sphere to be drawn in the coordinates (10,10,10)

Easy, just an offset to x, y, z, like this:
x = r * np.outer(np.cos(u), np.sin(v)) + 10
y = r * np.outer(np.sin(u), np.sin(v)) + 10
z = r * np.outer(np.ones(np.size(u)), np.cos(v)) + 10

Related

How to draw sphere with cylinder by formula with matplotlib

I have two formulas:
x^2 + y^2+z^2 = 6
(x-3)^2+y^2=4
So I have to draw this shapes by matplotlib on python.
My solution:
`
import math
import matplotlib.pyplot as plt
from pylab import *
import numpy as np
import matplotlib.patches as patches
from mpl_toolkits.mplot3d import Axes3D
from itertools import product, combinations
import mpl_toolkits.mplot3d.art3d as art3d
def task3():
fig = plt.figure()
ax = plt.axes(projection='3d')
coefs = (1, 1, 1) # Coefficients in a0/c x**2 + a1/c y**2 + a2/c z**2 = 1
# Radii corresponding to the coefficients:
rx, ry, rz = 1 / np.sqrt(coefs)
# Set of all spherical angles:
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
# Cartesian coordinates that correspond to the spherical angles:
# (this is the equation of an ellipsoid):
x = rx * np.outer(np.cos(u), np.sin(v))
y = ry * np.outer(np.sin(u), np.sin(v))
z = rz * np.outer(np.ones_like(u), np.cos(v))
ax.plot_surface(x, y, z, rstride=6, cstride=6,
cmap='viridis', edgecolor='none')
# ax.scatter(X, Y, Z, c=Z, cmap='viridis', label="xy")
radius = 0.3
height = 2.4
elevation = -1
resolution = 720
color = 'r'
x_center = 0.7
y_center = -0
a = np.linspace(x_center - radius, x_center + radius, resolution)
b = np.linspace(elevation, elevation + height, resolution)
X, Z = np.meshgrid(a, b)
Y = np.sqrt(radius ** 2 - (X - x_center) ** 2) + y_center # Pythagorean theorem
ax.plot_surface(X, Y, Z, rstride=6, cstride=6,
cmap='viridis', edgecolor='none')
ax.plot_surface(X, (2 * y_center - Y), Z, rstride=6, cstride=6,
cmap='viridis', edgecolor='none')
plt.show()
[![Result. I cant post images, but you can compile result and then you will see that my solution too approximate)
I want to do it correctly

How to animate a 3D plot, defined with three functions x=(), y=(), z=()?

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import mpl_toolkits.mplot3d as Axes3D
r = 20
h = 1.7
phi = np.linspace(0, 4*np.pi, 1000)
theta = np.linspace(-np.pi/4, np.pi/4, 1000)
#theta = np.arcsin(0.524)
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)
fig = plt.figure('Parametric pancake')
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z, '-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)
plt.title('Parametric pancake', fontweight = 'bold', fontsize = 16)
plt.show()
This code draws the plot, defined by the x, y and z equations. That is great, but I need to draw it, i.e. to have a point that draws the plot as it moves and not have a plot, thats already drawn. How do I make that happen? Furthermore, I need the plot to move periodically - the angle phi to continue to rotate and angle theta to move harmonically from -90 degrees to +90 degrees kind of like a pendulum. And the last thing is how do I make the point move in a loop so it does not stop when the plot is drawn, but continues to move along that plot?
You need to create a animate callback to update the data.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import mpl_toolkits.mplot3d as Axes3D
import matplotlib.animation as animation
r = 20
h = 1.7
N=1000
phi = np.linspace(0, 4*np.pi, N)
theta = np.linspace(-np.pi/4, np.pi/4, N)
#theta = np.arcsin(0.524)
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)
fig = plt.figure('Parametric pancake')
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim(x.min(),x.max())
ax.set_ylim(y.min(),y.max())
ax.set_zlim(z.min(),z.max())
pltdata, = ax.plot(x[:1], y[:1], z[:1], '-r', linewidth = 3)
lastPoint, = ax.plot(x[0], y[0], z[0], 'b', marker='o')
txt = ax.text(x[0], y[0], z[0]+0.5, 'i=0')
ax.set_xlabel('X', fontweight = 'bold', fontsize = 14)
ax.set_ylabel('Y', fontweight = 'bold', fontsize = 14)
ax.set_zlabel('Z', fontweight = 'bold', fontsize = 14)
plt.title('Parametric pancake', fontweight = 'bold', fontsize = 16)
def animate(i):
pltdata.set_data(x[:i+1], y[:i+1])
pltdata.set_3d_properties(z[:i+1])
lastPoint.set_data(x[i:i+1], y[i:i+1])
lastPoint.set_3d_properties(z[i:i+1])
txt.set_text(f"{i=}")
txt.set_x(x[i])
txt.set_y(y[i])
txt.set_z(z[i]+0.5)
return [pltdata, lastPoint, txt]
theAnim = animation.FuncAnimation(fig, animate, frames=N, interval=100, blit=True, repeat=False)
plt.show()
#theAnim.save('out.gif')

Output matplotlib plots from saving

I found a tutorial online for this matplotlib and numpy graph. The code runs smoothly, but there is no output. I have tried to save the graph as a file, but that does not seem to work.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
fig = plt.figure()
ax = plt.axes(projection="3d")
zline = np.linspace(0, 15, 1000)
xline = np.sin(zline)
yline = np.cos(zline)
ax.plot3D(xline, yline, zline, "gray") # Data for three-dimensional scattered points
zdata = 15 * np.random.random(100)
xdata = np.sin(zdata) + 0.1 * np.random.randn(100)
ydata = np.cos(zdata) + 0.1 * np.random.randn(100)
ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap="Greens");
def f(x, y):
return np.sin(np.sqrt(x ** 2 + y ** 2))
x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.contour3D(X, Y, Z, 50, cmap='binary')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z');
theta = 2 * np.pi * np.random.random(1000)
r = 6 * np.random.random(1000)
x = np.ravel(r * np.sin(theta))
y = np.ravel(r * np.cos(theta))
z = f(x, y)
ax = plt.axes(projection="3d")
ax.plot_trisurf(x, y, z,cmap="viridis", edgecolor="none");
The link to the website is https://www.edureka.co/blog/python-projects/. Surely there is some way to access the graphical user interface to display the plots?
Adding plt.show() at the end will display both of the graphs.

How to plot Saturn and its rings using matplotlib 3D?

I have managed to create a code that outputs a sphere and a ring around it but the ring doesn't look like its rounding the sphere...
Can anyone save me here?
Code:
import numpy as np
from matplotlib import pyplot as plt
import mpl_toolkits.mplot3d.axes3d
theta = np.linspace(0, 2.*np.pi, 100)
phi = np.linspace(0, 2*np.pi, 100)
theta, phi = np.meshgrid(theta, phi)
c, a = 10, 0.2
x = (c + a*np.cos(theta)) * np.cos(phi)
y = (c + a*np.cos(theta)) * np.sin(phi)
z = a * np.sin(theta)
fig = plt.figure()
ax1 = fig.add_subplot(111, projection='3d')
ax1.set_zlim(-10,10)
ax1.plot_surface(x, y, z, rstride=5, cstride=5, color='b', edgecolors='b')
ax1.view_init(36, 26)
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
x2 = 4 * np.outer(np.cos(u), np.sin(v))
y2 = 4 * np.outer(np.sin(u), np.sin(v))
z2 = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
ax1.plot_surface(x2, y2, z2, rstride=5, cstride=5, color='r')
plt.show()

Matplotlib parametric surface plot unexpected results, why?

I am trying to plot an ellipsoid so, I thought I would amend the example code for a sphere from the matplotlib 3D plotting page.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# Ellipsoid
u = np.linspace(-np.pi/2.0,np.pi/2.0,100)
v = np.linspace(-np.pi,np.pi,100)
x = 10 * np.outer(np.cos(u), np.cos(v))
y = 10 * np.outer(np.cos(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.sin(v))
# Sphere
#u = np.linspace(0, 2 * np.pi, 100)
#v = np.linspace(0, np.pi, 100)
#x = 10 * np.outer(np.cos(u), np.sin(v))
#y = 10 * np.outer(np.sin(u), np.sin(v))
#z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, rstride=4, cstride=4, cmap = cm.copper)
ax.set_xlabel('x-axis')
ax.set_ylabel('y-axis')
ax.set_zlabel('z-axis')
plt.show()
If you run the code you will see that the plot returns an aesthetically pleasing half inside out boat like surface but sadly not an ellipsoid.
Have included the sphere code (commented out) for comparison.
Is there something obvious here that I'm missing?
Why did you change the parametrization? Starting with the sphere as an example, you only have to change the semi-axis lengths:
# Ellipsoid
u = np.linspace(0, 2.*np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = 60 * np.outer(np.cos(u), np.sin(v))
y = 20 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))

Categories

Resources