$$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}[1]{\| #1 \|}$$ $$\newcommand{\inner}[2]{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$

# Chapter 1

$$\newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} }$$ $$\newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}}$$$$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}[1]{\| #1 \|}$$ $$\newcommand{\inner}[2]{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}[1]{\| #1 \|}$$ $$\newcommand{\inner}[2]{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$

Static Volume $$\PageIndex{1}$$ (Python):

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import mpl_toolkits.axes_grid1
%matplotlib widget

pi = np.pi
lowerLimit = -2
upperLimit = 2
step = .01

eq = "1-x**2"

def f(x):
return 1-x**2

xs = np.arange(lowerLimit, upperLimit+step, step)
ys = f(xs)
maximum = abs(ys).max()

fig = plt.figure('Volume Animated Circle Slices around X axis', figsize=(6,3))
ax1 = fig.gca(projection='3d')
plt.style.use('seaborn-pastel')
ax1.set_title('\nRegion under parabola ' + eq + '\n circular slices around x axis')

ax1.view_init(elev=45, azim=-90)

ax1.set_xlabel('X axis')
ax1.set_ylabel('Y axis')
ax1.set_zlabel('Z axis')

ax1.axes.set_xlim3d(lowerLimit,upperLimit)
ticks =  np.linspace(lowerLimit, upperLimit, 5)
ax1.axes.set_xticks(ticks)
ticks =  np.linspace(-maximum, maximum, 5)
ax1.axes.set_ylim3d(maximum, -maximum)
ax1.axes.set_yticks(ticks)
ax1.axes.set_zlim3d(-maximum, maximum)
ax1.axes.set_zticks(ticks)

for x in xs:
theta = -pi
a = []
b = []
c = []
while theta <= pi:
bx = np.cos(theta)*f(x)
cx = np.sin(theta)*f(x)
a.append(x)
b.append(bx)
c.append(cx)
theta += pi/36.0

circle, = ax1.plot3D(a, b, c, color='b')

plt.show()

Animated Square Slices $$\PageIndex{2}$$ (Python):

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation
%matplotlib widget

def square(startX, startY, startZ, width):
lines = []
lines.append([[startX, startX], [startY, startY+width], [startZ, startZ]])
lines.append([[startX, startX], [startY, startY], [startZ, startZ+width]])
lines.append([[startX, startX], [startY, startY+width], [startZ+width, startZ+width]])
lines.append([[startX, startX], [startY+width, startY+width], [startZ, startZ+width]])
return lines

x = np.arange(0, 1, .01)
y = 1-x**2
z = 0

def animate(i):
lines = square(i, 0, 0, 1-i**2)
for line in lines:
thisSquare = ax1.plot3D(line[0], line[1], line[2], color = 'b')
plt.draw()
return thisSquare

fig = plt.figure('Animated Squares', figsize=(6,3))
ax1 = fig.gca(projection='3d')
ax1.plot3D(x, y, z, color='b')
ax1.view_init(azim=45)
plt.style.use('seaborn-pastel')

ax1.set_title('Region under parabola y=1-x^2 in first quadrant \n square slices perpendicular to xy plane')

ax1.set_xlabel('X axis')
ax1.set_ylabel('Y axis')
ax1.set_zlabel('Z axis')

ax1.axes.set_xlim3d(0, 1)
ax1.axes.set_ylim3d(0, 1)
ax1.axes.set_zlim3d(0, 1)

ax1.set_zticks([0, 0.5, 1])
ax1.set_yticks([0, 0.5, 1])
ax1.set_xticks([0, 0.5, 1])

step = -.05
steps = np.arange(1, 0+step, step)
ani = FuncAnimation(fig, animate, steps, interval=400, blit=True, repeat=False)

plt.show()

Disc Integration around X-Axis $$\PageIndex{3}$$ (Python):

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation
from matplotlib.ticker import FormatStrFormatter
import mpl_toolkits.axes_grid1
import matplotlib.widgets as widgets
import sympy as sp
from sympy.parsing.sympy_parser import parse_expr
%matplotlib widget

x = sp.symbols('x')
eq = '1-x^2'
pi = np.pi
oneDecimal = '%.1f'
noDecimals = '%.0f'
lowerFlag = False

colourSchemes = []
colourSchemes.append(['#00b8ff', '#1500ff', '#3445c3', '#26477e', '#1e225c']) #Blues
colourSchemes.append(['#9400D3', '#00ff00', '#ffff00', '#FFA500', '#ff0000']) #Purple(low) to red(high)
colourSchemes.append(['#009ee3', '#00a3c9', '#00a6aa', '#00a989', '#2eac66']) #Blue(low) to green(high)
colourChoice = 0

def f(x):
return 1 - x**2

def on_colour_change(label):
global colourChoice
colourDict = {'Blues': 0, 'Purple-Red': 1, 'Blue-Green': 2}
colourChoice = colourDict[label]
restart()

def limit_change(newMin, newMax):
global lowerLimit, upperLimit, step, x, part, maximum, minimum, firstTime, function

lowerLimit = newMin
upperLimit = newMax
step =(upperLimit-lowerLimit)/100.0
x = np.arange(lowerLimit, upperLimit+step, step)

part = (maximum - minimum)/5.0
if firstTime:
firstTime = False
else:
restart()

def checkValue(entry):
global lowerFlag, errMsg
try:
newLimit = float(entry)
errMsg.set_text('')
except:
errMsg.set_text('ERROR: Numbers only!')
if lowerFlag:
newLimit = lowerLimit
else:
newLimit = upperLimit

if lowerFlag:
if newLimit != upperLimit:
newLowerLimit = newLimit
newUpperLimit = upperLimit
if newLimit > upperLimit:
newLowerLimit = upperLimit
newUpperLimit = newLimit

else:
if newLimit != lowerLimit:
newUpperLimit = newLimit
newLowerLimit = lowerLimit
if newLimit < lowerLimit:
newUpperLimit = lowerLimit
newLowerLimit = newLimit

lowerFlag = False
limit_change(newLowerLimit, newUpperLimit)

def setLowerFlag(entry):
global lowerFlag
lowerFlag = True
checkValue(entry)

def saveFigure(entry):
"""Routine to save a figure -- Needs Work, Simpy Restarts Animation for now"""
"""
global ani, plt
ani.stop()
saveFile = './Images/' + 'ImageSaveTest' + '.png'
plt.savefig(saveFile, bbox_inches='tight', transparent=True)
"""
restart()

def setUpOptions(selection=0):
global radio_colourChoice, text_llimit, text_ulimit, check_save

t1 = fig.text(0, .76,'Colour scheme', fontsize=9)

active=selection)

stringLimit = ''
text_llimit = widgets.TextBox(llimit_ax1, "Lower limit ", initial=stringLimit,
text_llimit.on_submit(setLowerFlag)

text_ulimit = widgets.TextBox(ulimit_ax1, "Upper limit ", initial=stringLimit,
text_ulimit.on_submit(checkValue)

check_save = widgets.Button(save_ax1, label=u'$\u25F3$', color='.95')
check_save.on_clicked(saveFigure)

class Animator(FuncAnimation):
def __init__(self, fig, func, frames=None, init_func=None,fargs=None,
save_count=None, mini=0, maxi=100, pos=(0.3, 0.01), **kwargs):
self.i = 0
self.min=mini
self.max=maxi
self.runs = True
self.forwards = True
self.fig = fig
self.func = func
self.setup(pos)
FuncAnimation.__init__(self,self.fig, self.update, frames=self.play(),
init_func=init_func, fargs=fargs,
save_count=save_count, **kwargs )
def play(self):
while self.runs:
self.i = self.i+self.forwards-(not self.forwards)
if self.i > self.min and self.i < self.max:
yield self.i
else:
self.stop()
yield self.i

def start(self):
self.runs=True
self.event_source.start()

def stop(self, event=None):
self.runs = False
self.event_source.stop()

def forward(self, event=None):
self.forwards = True
self.start()

def oneforward(self, event=None):
self.forwards = True
self.onestep()

def onestep(self):
if self.i > self.min and self.i < self.max:
self.i = self.i+self.forwards-(not self.forwards)
elif self.i == self.min and self.forwards:
self.i+=1
elif self.i == self.max and not self.forwards:
self.i-=1
self.func(self.i)
self.slider.set_val(self.i)
self.fig.canvas.draw_idle()

def setup(self, pos):
sax = self.fig.add_axes([pos[0],pos[1], .42, 0.04])
divider = mpl_toolkits.axes_grid1.make_axes_locatable(sax)

fax = divider.append_axes("right", size="80%", pad=0.01)
ofax = divider.append_axes("right", size="80%", pad=0.01)
sliderax = divider.append_axes("right", size="500%", pad=0.01)

self.button_stop = widgets.Button(sax, label=u'$\u25A0$')
self.button_forward = widgets.Button(fax, label=u'$\u25B6$')
self.button_oneforward = widgets.Button(ofax, label=u'$\u29D0$')

self.button_stop.on_clicked(self.stop)
self.button_forward.on_clicked(self.forward)
self.button_oneforward.on_clicked(self.oneforward)
self.slider = widgets.Slider(sliderax, '', self.min, self.max,
valinit=self.min, valfmt='%1.0f%%')
self.slider.on_changed(self.set_pos)

def set_pos(self,i):
self.i = int(self.slider.val)
self.func(self.i)

def update(self, i):
self.slider.set_val(i)

theta = np.arange(0, 2*pi+.1, .1)
xs = np.full(len(ys), spot)
return xs, ys, zs

def chooseColour(val):
for j in range(4):
if val < minimum+(j+1)*part:
return j
return 4

def animate(i):
incrementedX = x[i]
incrementedY = np.abs(f(x[i]))
xs, ys, zs = circle(incrementedX, incrementedY)
heatColour = colourSchemes[colourChoice][chooseColour(incrementedY)]
line, = ax1.plot3D(xs, ys, zs, color = heatColour)
return line,

def init():
plt.style.use('seaborn-pastel')
ax1.set_title('\nRegion under parabola ' + eq + '\n circular slices around x axis')

ax1.view_init(elev=45, azim=-90)

ax1.set_xlabel('X axis')
ax1.set_ylabel('Y axis')
ax1.set_zlabel('Z axis')

fmt2Use = oneDecimal

if maximum >= 100:
fmt2Use = noDecimals

ax1.w_xaxis.set_major_formatter(FormatStrFormatter(oneDecimal))
ax1.w_yaxis.set_major_formatter(FormatStrFormatter(fmt2Use))
ax1.w_zaxis.set_major_formatter(FormatStrFormatter(fmt2Use))

ax1.axes.set_xlim3d(lowerLimit,upperLimit)
ticks =  np.linspace(lowerLimit, upperLimit, 5)
ax1.axes.set_xticks(ticks)
ticks =  np.linspace(-maximum, maximum, 5)
ax1.axes.set_ylim3d(maximum, -maximum)
ax1.axes.set_yticks(ticks)
ax1.axes.set_zlim3d(-maximum, maximum)
ax1.axes.set_zticks(ticks)

setUpOptions(colourChoice)

def restart():
ax1.cla()
llimit_ax1.cla()
ulimit_ax1.cla()
firstTime = False
init()
ani.i = 0
ani.start()

lowerLimit = -pi
upperLimit = pi
firstTime = True
g = np.vectorize(f)
limit_change(lowerLimit, upperLimit)

fig = plt.figure('Volume Animated Circle Slices around X axis', figsize=(6,3))
ax1 = fig.gca(projection='3d')
colour_ax1 = fig.add_axes([0, .6, .19, .15]) # [x start, y start, width, height]
llimit_ax1 = fig.add_axes([.14, .5, .09, .05])
ulimit_ax1 = fig.add_axes([.14, .4, .09, .05])
save_ax1 = fig.add_axes([.09, .3, .04, .06])
errMsg = fig.text(0, .1,'', fontsize=9, color='b')
init()

ani = Animator(fig, animate)

plt.show()

Chapter 1 is shared under a not declared license and was authored, remixed, and/or curated by LibreTexts.