8  Visual Demos

Somewhat experimental, and better on a larger screen.

8.1 Cauchy’s Mean Value Theorem

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true

import matplotlib.pyplot as plt
import numpy as np
from shiny.express import ui, input, render

sin = np.sin

with ui.tags.head():
    ui.tags.link(
        rel="stylesheet",
        href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css"
    ),
    ui.tags.script(src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.js"),
    ui.tags.script(src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/contrib/auto-render.min.js"),
    ui.tags.script("""
        document.addEventListener('DOMContentLoaded', function() {
            renderMathInElement(document.body, {
                    delimiters: [
                    {left: "$$", right: "$$", display: true},
                    {left: "\\[", right: "\\]", display: true},
                    {left: "$", right: "$", display: false},
                    {left: "\\(", right: "\\)", display: false}
                ]
            });
        });
    """)

ui.tags.style(
    """
    body { background: #C8E0FF !important; }
    .irs-bar { background: #0054A9 !important; }
    .irs-handle { background: #0054A9 !important; }
    .irs-single { background: #0054A9 !important; color: #FFFFFF !important; }
    .irs-min { background:#99CBFF !important; color: #000000 !important; }
    .irs-max { background:#99CBFF !important; color: #000000 !important; }
    .control-label { display: block; text-align: center; }
    .shiny-input-container { margin:auto; }
    """
)

a = -0.5
b = 10

npts = 400

ui.input_slider(id="t",label="$t$ slider",min=a,max=b,value=2,step=0.25)

@render.plot(alt="Graph of the tangent to the parametric curve at $t$.")
def ball():
    t = input.t()

    def f(x):
        return (x+2)/(x**2+1)
    def g(x):
        return (x**2+20*x-2)/(x**2+30)

    def df(x):
        return -(-1 + 4*x + x**2)/(1 + x**2)**2
    def dg(x):
        return (600 + 64*x - 20*x**2)/(30 + x**2)**2

    U = [a + (b-a)*i/npts for i in range(0,npts+1)]
    X = [g(u) for u in U]
    Y = [f(u) for u in U]

    plt.figure(facecolor='#C8E0FF')

    plt.plot(X,Y,color="#0054A9",label="parametric curve $(g(t),f(t))$")
    plt.plot([g(a),g(b)],[f(a),f(b)],color="#00A954",label="secant line")
    plt.plot(g(a),f(a),color="#0054A9",markersize=5,marker="o")
    plt.plot(g(b),f(b),color="#0054A9",markersize=5,marker="o")

    ax = plt.gca()
    ax.set_aspect('equal')
    ax.set_facecolor('#C8E0FF')

    ax.axline((g(t),f(t)),slope=df(t)/dg(t),color="#FF9933",label="tangent at $(g(t),f(t))$")
    plt.plot(g(t),f(t),color="#FF9933",markersize=5,marker="o")
    ax.legend(facecolor='#C8E0FF',frameon=False)

8.2 \(L_p\) Norms

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true

import matplotlib.pyplot as plt
import numpy as np
from shiny.express import ui, input, render

with ui.tags.head():
    ui.tags.link(
        rel="stylesheet",
        href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css"
    ),
    ui.tags.script(src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.js"),
    ui.tags.script(src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/contrib/auto-render.min.js"),
    ui.tags.script("""
        document.addEventListener('DOMContentLoaded', function() {
            renderMathInElement(document.body, {
                    delimiters: [
                    {left: "$$", right: "$$", display: true},
                    {left: "\\[", right: "\\]", display: true},
                    {left: "$", right: "$", display: false},
                    {left: "\\(", right: "\\)", display: false}
                ]
            });
        });
    """)

ui.tags.style(
    """
    body { background: #C8E0FF !important; }
    .irs-bar { background: #0054A9 !important; }
    .irs-handle { background: #0054A9 !important; }
    .irs-single { background: #0054A9 !important; color: #FFFFFF !important; }
    .irs-min { background:#99CBFF !important; color: #000000 !important; }
    .irs-max { background:#99CBFF !important; color: #000000 !important; }
    .control-label { display: block; text-align: center; }
    """
)

ui.input_slider(id="p",label="Ball and sphere for the $L_p$ norm.",min=1,max=8,value=2,step=0.5).add_style("margin:auto;") # center the slider

@render.plot(alt="Unit ball and sphere for the $L_p$ norm.")
def ball():
    p = input.p()
    npts = 200

    X = [-1 + 2*x/npts for x in range(0,npts+1)]
    Ytop = [(1-abs(x)**p)**(1/p) for x in X]
    Ybot = [-(1-abs(x)**p)**(1/p) for x in X]

    plt.figure(facecolor='#C8E0FF')
    plt.plot(X,Ytop,color="#0054A9")
    plt.plot(X,Ybot,color="#0054A9")
    plt.fill_between(X,Ytop,color="#99CBFF")
    plt.fill_between(X,Ybot,color="#99CBFF")
    plt.xlim(-1.4,1.4)
    plt.ylim(-1.4,1.4)
    ax = plt.gca()
    ax.set_aspect('equal')
    ax.set_facecolor('#C8E0FF')