{ "hash": "0a512672c93bc4dc2b75c39061f4fb57", "result": { "markdown": "# The Graph of a Function\n\n\n\nThis section will use the following packages:\n\n``` {.julia .cell-code}\nusing CalculusWithJulia\nusing Plots\n```\n\n\n\n\n---\n\n\nA scalar, univariate function, such as $f(x) = 1 - x^2/2$, can be thought of in many different ways. For example:\n\n\n * It can be represented through a rule of what it does to $x$, as above. This is useful for computing numeric values.\n * it can be interpreted verbally, as in *square* $x$, take half then *subtract* from one. This can give clarity to what the function does.\n * It can be thought of in terms of its properties: a polynomial, continuous, $U$-shaped, an approximation for $\\cos(x)$ near $0$, $\\dots$\n * it can be visualized graphically. This is useful for seeing the qualitative behavior of a function.\n\n\nThe graph of a univariate function is just a set of points in the Cartesian plane. These points come from the relation $(x,f(x))$ that defines the function. Operationally, a sketch of the graph will consider a handful of such pairs and then the rest of the points will be imputed.\n\n\nFor example, a typical approach to plot $f(x) = 1 - x^2/2$ would be to choose some values for $x$ and find the corresponding values of $y$. This might be organized in a \"T\"-table:\n\n\n\n```{verbatim}\n x | y\n--------\n-2 | -1\n-1 | 1/2\n 0 | 1\n 1 | 1/2\n 2 | -1\n 3 | -7/2\n```\n\n\nThese pairs would be plotted in a Cartesian plane and then connected with curved lines. A good sketch is aided by knowing ahead of time that this function describes a parabola which is curving downwards.\n\n\nWe note that this sketch would not include *all* the pairs $(x,f(x))$, as their extent is infinite, rather a well chosen collection of points over some finite domain.\n\n\n## Graphing a function with Julia\n\n\n`Julia` has several different options for rendering graphs, all in external packages. We will focus in these notes on the `Plots` package, which provides a common interface to several different plotting backends. (Click through for instructions for plotting with the [Makie](../alternatives/makie_plotting.html) package or the [PlotlyLight](alternatives/plotly_plotting.html) package.) At the top of this section the accompanying `CalculusWithJulia` package and the `Plots` package were loaded with the `using` command, like this:\n\n``` {.julia .cell-code}\nusing CalculusWithJulia\nusing Plots\n```\n\n\n:::{.callout-note}\n## Note\n`Plots` is a frontend for one of several backends. `Plots` comes with a backend for web-based graphics (call `plotly()` to specify that); a backend for static graphs (call `gr()` for that). If the `PyPlot` package is installed, calling `pyplot()` will set that as a backend. For terminal usage, if the `UnicodePlots` package is installed, calling `unicodeplots()` will enable that usage. There are still other backends.\n\n:::\n\nThe `plotly` backend is part of the `Plots` package, as is `gr`. Other backends require installation, such as `PyPlot` and `PlotlyJS`. We use `gr` in these notes, for the most part. (The `plotly` backend is also quite nice for interactive usage, but doesn't work as well with the static HTML pages.)\n\n\nWith `Plots` loaded, it is straightforward to graph a function.\n\n\nFor example, to graph $f(x) = 1 - x^2/2$ over the interval $[-3,3]$ we have:\n\n::: {.cell execution_count=5}\n``` {.julia .cell-code}\nf(x) = 1 - x^2/2\nplot(f, -3, 3)\n```\n\n::: {.cell-output .cell-output-display execution_count=5}\n{}\n:::\n:::\n\n\nThe `plot` command does the hard work behind the scenes. It needs $2$ pieces of information declared:\n\n\n * **What** to plot. With this invocation, this detail is expressed by passing a function object to `plot`\n * **Where** to plot; the `xmin` and `xmax` values. As with a sketch, it is impossible in this case to render a graph with all possible $x$ values in the domain of $f$, so we need to pick some viewing window. In the example this is $[-3,3]$ which is expressed by passing the two endpoints as the second and third arguments.\n\n\nPlotting a function is then this simple: `plot(f, xmin, xmax)`.\n\n\n> *A basic template:* Many operations we meet will take the form `action(function, args...)`, as the call to `plot` does. The template shifts the focus to the action to be performed. This is a [declarative](http://en.wikipedia.org/wiki/Declarative_programming) style, where the details to execute the action are only exposed as needed.\n\n\n\n:::{.callout-note}\n## Note\nThe time to first plot can feel sluggish, but subsequent plots will be speedy. See the technical note at the end of this section for an explanation.\n\n:::\n\nLet's see some other graphs.\n\n\nThe `sin` function over one period is plotted through:\n\n::: {.cell execution_count=6}\n``` {.julia .cell-code}\nplot(sin, 0, 2pi)\n```\n\n::: {.cell-output .cell-output-display execution_count=6}\n{}\n:::\n:::\n\n\nWe can make a graph of $f(x) = (1+x^2)^{-1}$ over $[-3,3]$ with\n\n::: {.cell hold='true' execution_count=7}\n``` {.julia .cell-code}\nf(x) = 1 / (1 + x^2)\nplot(f, -3, 3)\n```\n\n::: {.cell-output .cell-output-display execution_count=7}\n{}\n:::\n:::\n\n\nA graph of $f(x) = e^{-x^2/2}$ over $[-2,2]$ is produced with:\n\n::: {.cell hold='true' execution_count=8}\n``` {.julia .cell-code}\nf(x) = exp(-x^2/2)\nplot(f, -2, 2)\n```\n\n::: {.cell-output .cell-output-display execution_count=8}\n{}\n:::\n:::\n\n\nWe could skip the first step of defining a function by using an *anonymous function*. For example, to plot $f(x) = \\cos(x) - x$ over $[0, \\pi/2]$ we could do:\n\n::: {.cell execution_count=9}\n``` {.julia .cell-code}\nplot(x -> cos(x) - x, 0, pi/2)\n```\n\n::: {.cell-output .cell-output-display execution_count=9}\n{}\n:::\n:::\n\n\nAnonymous functions are especially helpful when parameterized functions are involved:\n\n::: {.cell hold='true' execution_count=10}\n``` {.julia .cell-code}\nmxplusb(x; m=1, b=0) = m*x + b\nplot(x -> mxplusb(x; m=-1, b=1), -1, 2)\n```\n\n::: {.cell-output .cell-output-display execution_count=10}\n{}\n:::\n:::\n\n\nHad we parameterized using the `f(x,p)` style, the result would be similar:\n\n::: {.cell execution_count=11}\n``` {.julia .cell-code}\nfunction mxplusb(x, p)\n m, b = p.m, p.b\n m * x + b\nend\nplot(x -> mxplusb(x, (m=-1, b=1)), -1, 2)\n```\n\n::: {.cell-output .cell-output-display execution_count=11}\n{}\n:::\n:::\n\n\n:::{.callout-note}\n## Note\nThe function object in the general pattern `action(function, args...)` is commonly specified in one of three ways: by a name, as with `f`; as an anonymous function; or as the return value of some other action through composition.\n\n:::\n\nAnonymous functions are also created by `Julia's` `do` notation, which is useful when the first argument to function (like `plot`) accepts a function:\n\n::: {.cell execution_count=12}\n``` {.julia .cell-code}\nplot(0, pi/2) do x\n cos(x) - x\nend\n```\n\n::: {.cell-output .cell-output-display execution_count=12}\n{}\n:::\n:::\n\n\nThe `do` notation can be a bit confusing to read when unfamiliar, though its convenience makes it appealing.\n\n\n:::{.callout-note}\n## Note\nSome types we will encounter, such as the one for symbolic values or the special polynomial one, have their own `plot` recipes that allow them to be plotted similarly as above, even though they are not functions.\n\n:::\n\n---\n\nMaking a graph with `Plots` is easy, but producing a graph that is informative can be a challenge, as the choice of a viewing window can make a big difference in what is seen. For example, trying to make a graph of $f(x) = \\tan(x)$, as below, will result in a bit of a mess - the chosen viewing window crosses several places where the function blows up:\n\n::: {.cell hold='true' execution_count=13}\n``` {.julia .cell-code}\nf(x) = tan(x)\nplot(f, -10, 10)\n```\n\n::: {.cell-output .cell-output-display execution_count=13}\n{}\n:::\n:::\n\n\nThough this graph shows the asymptote structure and periodicity, it doesn't give much insight into each period or even into the fact that the function is periodic.\n\n\n## The details of graph making\n\n\nThe actual details of making a graph of $f$ over $[a,b]$ are pretty simple and follow the steps in making a \"T\"-table:\n\n\n * A set of $x$ values are created between $a$ and $b$.\n * A corresponding set of $y$ values are created.\n * The pairs $(x,y)$ are plotted as points and connected with straight lines.\n\n\nThe only real difference is that when drawing by hand, we might know to curve the lines connecting points based on an analysis of the function. As `Julia` doesn't consider this, the points are connected with straight lines ā like a dot-to-dot puzzle.\n\n\nIn general, the `x` values are often generated by `range` or the `colon` operator and the `y` values produced by mapping or broadcasting a function over the generated `x` values.\n\n\nHowever, the plotting directive `plot(f, xmin, xmax)` calls an adaptive algorithm to use more points where needed, as judged by `PlotUtils.adapted_grid(f, (xmin, xmax))`. It computes both the `x` and `y` values. This algorithm is wrapped up into the `unzip(f, xmin, xmax)` function from `CalculusWithJulia`. The algorithm adds more points where the function is more \"curvy\" and uses fewer points where it is \"straighter.\" Here we see the linear function is identified as needing far fewer points than the oscillating function when plotted over the same range:\n\n::: {.cell execution_count=14}\n``` {.julia .cell-code}\npts_needed(f, xmin, xmax) = length(unzip(f, xmin, xmax)[1])\npts_needed(x -> 10x, 0, 10), pts_needed(x -> sin(10x), 0, 10)\n```\n\n::: {.cell-output .cell-output-display execution_count=14}\n```\n(31, 1605)\n```\n:::\n:::\n\n\n(In fact, the `21` is the minimum number of points used for any function; a linear function only needs two.)\n\n---\n\n\nFor instances where a *specific* set of $x$ values is desired to be used, the `range` function or colon operator can be used to create the $x$ values and broadcasting used to create the $y$ values. For example, if we were to plot $f(x) = \\sin(x)$ over $[0,2\\pi]$ using $10$ points, we might do:\n\n::: {.cell execution_count=15}\n``` {.julia .cell-code}\nšs = range(0, 2pi, length=10)\nšs = sin.(šs)\n```\n\n::: {.cell-output .cell-output-display execution_count=15}\n```\n10-element Vector{Float64}:\n 0.0\n 0.6427876096865393\n 0.984807753012208\n 0.8660254037844387\n 0.3420201433256689\n -0.34202014332566866\n -0.8660254037844385\n -0.9848077530122081\n -0.6427876096865396\n -2.4492935982947064e-16\n```\n:::\n:::\n\n\nFinally, to plot the set of points and connect with lines, the $x$ and $y$ values are passed along as vectors:\n\n::: {.cell execution_count=16}\n``` {.julia .cell-code}\nplot(šs, šs)\n```\n\n::: {.cell-output .cell-output-display execution_count=16}\n{}\n:::\n:::\n\n\nThis plots the points as pairs and then connects them in order using straight lines. Basically, it creates a dot-to-dot graph. The above graph looks primitive, as it doesn't utilize enough points.\n\n\n##### Example: Reflections\n\n\nThe graph of a function may be reflected through a line, as those seen with a mirror. For example, a reflection through the $y$ axis takes a point $(x,y)$ to the point $(-x, y)$. We can easily see this graphically, when we have sets of $x$ and $y$ values through a judiciously placed minus sign.\n\n\nFor example, to plot $\\sin(x)$ over $(-\\pi,\\pi)$ we might do:\n\n::: {.cell execution_count=17}\n``` {.julia .cell-code}\nxs = range(-pi, pi, length=100)\nys = sin.(xs)\nplot(xs, ys)\n```\n\n::: {.cell-output .cell-output-display execution_count=17}\n{}\n:::\n:::\n\n\nTo reflect this graph through the $y$ axis, we only need to plot `-xs` and not `xs`:\n\n::: {.cell execution_count=18}\n``` {.julia .cell-code}\nplot(-xs, ys)\n```\n\n::: {.cell-output .cell-output-display execution_count=18}\n{}\n:::\n:::\n\n\nLooking carefully we see there is a difference. (How?)\n\n\nThere are four very common reflections:\n\n\n * reflection through the $y$-axis takes $(x,y)$ to $(-x, y)$.\n * reflection through the $x$-axis takes $(x,y)$ to $(x, -y)$.\n * reflection through the origin takes $(x,y)$ to $(-x, -y)$.\n * reflection through the line $y=x$ takes $(x,y)$ to $(y,x)$.\n\n\nFor the $\\sin(x)$ graph, we see that reflecting through the $x$ axis produces the same graph as reflecting through the $y$ axis:\n\n::: {.cell execution_count=19}\n``` {.julia .cell-code}\nplot(xs, -ys)\n```\n\n::: {.cell-output .cell-output-display execution_count=19}\n{}\n:::\n:::\n\n\nHowever, reflecting through the origin leaves this graph unchanged:\n\n::: {.cell execution_count=20}\n``` {.julia .cell-code}\nplot(-xs, -ys)\n```\n\n::: {.cell-output .cell-output-display execution_count=20}\n{}\n:::\n:::\n\n\n> An *even function* is one where reflection through the $y$ axis leaves the graph unchanged. That is, $f(-x) = f(x)$. An *odd function* is one where a reflection through the origin leaves the graph unchanged, or symbolically $f(-x) = -f(x)$.\n\n\n\nIf we try reflecting the graph of $\\sin(x)$ through the line $y=x$, we have:\n\n::: {.cell execution_count=21}\n``` {.julia .cell-code}\nplot(ys, xs)\n```\n\n::: {.cell-output .cell-output-display execution_count=21}\n{}\n:::\n:::\n\n\nThis is the graph of the equation $x = \\sin(y)$, but is not the graph of a function as the same $x$ can map to more than one $y$ value. (The new graph does not pass the \"vertical line\" test.)\n\n\nHowever, for the sine function we can get a function from this reflection if we choose a narrower viewing window:\n\n::: {.cell hold='true' execution_count=22}\n``` {.julia .cell-code}\nxs = range(-pi/2, pi/2, length=100)\nys = sin.(xs)\nplot(ys, xs)\n```\n\n::: {.cell-output .cell-output-display execution_count=22}\n{}\n:::\n:::\n\n\nThe graph is that of the \"inverse function\" for $\\sin(x), x \\text{ in } [-\\pi/2, \\pi/2]$.\n\n\n#### The `plot(xs, f)` syntax\n\n\nWhen plotting a univariate function there are three basic patterns that can be employed. We have examples above of:\n\n\n * `plot(f, xmin, xmax)` uses an adaptive algorithm to identify values for $x$ in the interval `[xmin, xmas]`,\n * `plot(xs, f.(xs))` to manually choose the values of $x$ to plot points for, and\n\n\nFinally there is a merging of these following either of these patterns:\n\n\n * `plot(f, xs)` *or* `plot(xs, f)`\n\n\nBoth require a manual choice of the values of the $x$-values to plot, but the broadcasting is carried out in the `plot` command. This style is convenient, for example, to down sample the $x$ range to see the plotting mechanics, such as:\n\n::: {.cell execution_count=23}\n``` {.julia .cell-code}\nplot(0:pi/4:2pi, sin)\n```\n\n::: {.cell-output .cell-output-display execution_count=23}\n{}\n:::\n:::\n\n\n#### NaN values\n\n\nAt times it is not desirable to draw lines between each succesive point. For example, if there is a discontinuity in the function or if there were a vertical asymptote, such as what happens at $0$ with $f(x) = 1/x$.\n\n\nThe most straightforward plot is dominated by the vertical asymptote at $x=0$:\n\n::: {.cell execution_count=24}\n``` {.julia .cell-code}\nq(x) = 1/x\nplot(q, -1, 1)\n```\n\n::: {.cell-output .cell-output-display execution_count=24}\n{}\n:::\n:::\n\n\nWe can attempt to improve this graph by adjusting the viewport. The *viewport* of a graph is the $x$-$y$ range of the viewing window. By default, the $y$-part of the viewport is determined by the range of the function over the specified interval, $[a,b]$. As just seen, this approach can produce poor graphs. The `ylims=(ymin, ymax)` argument can modify what part of the $y$ axis is shown. (Similarly `xlims=(xmin, xmax)` will modify the viewport in the $x$ direction.)\n\n\nAs we see, even with this adjustment, the spurious line connecting the points with $x$ values closest to $0$ is still drawn:\n\n::: {.cell execution_count=25}\n``` {.julia .cell-code}\nplot(q, -1, 1, ylims=(-10,10))\n```\n\n::: {.cell-output .cell-output-display execution_count=25}\n{}\n:::\n:::\n\n\nThe dot-to-dot algorithm, at some level, assumes the underlying function is continuous; here $q(x)=1/x$ is not.\n\n\nThere is a convention for most plotting programs that **if** the $y$ value for a point is `NaN` that no lines will connect to that point, `(x,NaN)`. `NaN` conveniently appears in many cases where a plot may have an issue, though not with $1/x$ as `1/0` is `Inf` and not `NaN`. (Unlike, say, `0/0` which is NaN.)\n\n\nHere is one way to plot $q(x) = 1/x$ over $[-1,1]$ taking advantage of this convention:\n\n::: {.cell hold='true' execution_count=26}\n``` {.julia .cell-code}\nxs = range(-1, 1, length=251)\nys = q.(xs)\nys[xs .== 0.0] .= NaN\nplot(xs, ys)\n```\n\n::: {.cell-output .cell-output-display execution_count=26}\n{}\n:::\n:::\n\n\nBy using an odd number of points, we should have that $0.0$ is amongst the `xs`. The next to last line replaces the $y$ value that would be infinite with `NaN`.\n\n\nAs a recommended alternative, we might modify the function so that if it is too large, the values are replaced by `NaN`. Here is one such function consuming a function and returning a modified function put to use to make this graph:\n\n::: {.cell execution_count=27}\n``` {.julia .cell-code}\nrangeclamp(f, hi=20, lo=-hi; replacement=NaN) = x -> lo < f(x) < hi ? f(x) : replacement\nplot(rangeclamp(x -> 1/x), -1, 1)\n```\n\n::: {.cell-output .cell-output-display execution_count=27}\n{}\n:::\n:::\n\n\n(The `clamp` function is a base `Julia` function which clamps a number between `lo` and `hi`, returning `lo` or `hi` if `x` is outside that range.)\n\n\n## Layers\n\n\nGraphing more than one function over the same viewing window is often desirable. Though this is easily done in `Plots` by specifying a vector of functions as the first argument to `plot` instead of a single function object, we instead focus on building the graph layer by layer.\n\n\nFor example, to see that a polynomial and the cosine function are \"close\" near $0$, we can plot *both* $\\cos(x)$ and the function $f(x) = 1 - x^2/2$ over $[-\\pi/2,\\pi/2]$:\n\n::: {.cell hold='true' execution_count=28}\n``` {.julia .cell-code}\nf(x) = 1 - x^2/2\nplot(cos, -pi/2, pi/2, label=\"cos\")\nplot!(f, -pi/2, pi/2, label=\"f\")\n```\n\n::: {.cell-output .cell-output-display execution_count=28}\n{}\n:::\n:::\n\n\nAnother useful function to add to a plot is one to highlight the $x$ axis. This makes identifying zeros of the function easier. The anonymous function `x -> 0` will do this. But, perhaps less cryptically, so will the base function `zero`. For example\n\n::: {.cell hold='true' execution_count=29}\n``` {.julia .cell-code}\nf(x) = x^5 - x + 1\nplot(f, -1.5, 1.4, label=\"f\")\nplot!(zero, label=\"zero\")\n```\n\n::: {.cell-output .cell-output-display execution_count=29}\n{}\n:::\n:::\n\n\n(The job of `zero` is to return \"$0$\" in the appropriate type. There is also a similar `one` function in base `Julia`.)\n\n\nThe `plot!` call adds a layer. We could still specify the limits for the plot, though as this can be computed from the figure, to plot `zero` we let `Plots` do it.\n\n\nFor another example, suppose we wish to plot the function $f(x)=x\\cdot(x-1)$ over the interval $[-1,2]$ and emphasize with points the fact that $0$ and $1$ are zeros. We can do this with three layers: the first to graph the function, the second to emphasize the $x$ axis, the third to graph the points.\n\n::: {.cell hold='true' execution_count=30}\n``` {.julia .cell-code}\nf(x) = x*(x-1)\nplot(f, -1, 2, legend=false) # turn off legend\nplot!(zero)\nscatter!([0,1], [0,0])\n```\n\n::: {.cell-output .cell-output-display execution_count=30}\n{}\n:::\n:::\n\n\nThe $3$ main functions used in these notes for adding layers are:\n\n\n * `plot!(f, a, b)` to add the graph of the function `f`; also `plot!(xs, ys)`\n * `scatter!(xs, ys)` to add points $(x_1, y_1), (x_2, y_2), \\dots$.\n * `annotate!((x,y, label))` to add a label at $(x,y)$\n\n\n:::{.callout-warning}\n## Warning\nJulia has a convention to use functions named with a `!` suffix to indicate that they mutate some object. In this case, the object is the current graph, though it is implicit. Both `plot!`, `scatter!`, and `annotate!` (others too) do this by adding a layer.\n\n:::\n\n## Additional arguments\n\n\nThe `Plots` package provides many arguments for adjusting a graphic, here we mention just a few of the [attributes](https://docs.juliaplots.org/latest/attributes/):\n\n\n * `plot(..., title=\"main title\", xlab=\"x axis label\", ylab=\"y axis label\")`: add title and label information to a graphic\n * `plot(..., color=\"green\")`: this argument can be used to adjust the color of the drawn figure (color can be a string,`\"green\"`, or a symbol, `:green`, among other specifications)\n * `plot(..., linewidth=5)`: this argument can be used to adjust the width of drawn lines\n * `plot(..., xlims=(a,b), ylims=(c,d)`: either or both `xlims` and `ylims` can be used to control the viewing window\n * `plot(..., linestyle=:dash)`: will change the line style of the plotted lines to dashed lines. Also `:dot`, ...\n * `plot(..., aspect_ratio=:equal)`: will keep $x$ and $y$ axis on same scale so that squares look square.\n * `plot(..., legend=false)`: by default, different layers will be indicated with a legend, this will turn off this feature\n * `plot(..., label=\"a label\")` the `label` attribute will show up when a legend is present. Using an empty string, `\"\"`, will suppress add the layer to the legend.\n\n\nFor plotting points with `scatter`, or `scatter!` the markers can be adjusted via\n\n\n * `scatter(..., markersize=5)`: increase marker size\n * `scatter(..., marker=:square)`: change the marker (uses a symbol, not a string to specify)\n\n\nOf course, zero, one, or more of these can be used on any given call to `plot`, `plot!`, `scatter` or `scatter!`.\n\n\n## Graphs of parametric equations\n\n\nIf we have two functions $f(x)$ and $g(x)$ there are a few ways to investigate their joint behavior. As just mentioned, we can graph both $f$ and $g$ over the same interval using layers. Such a graph allows an easy comparison of the shape of the two functions and can be useful in solving $f(x) = g(x)$. For the latter, the graph of $h(x) = f(x) - g(x)$ is also of value: solutions to $f(x)=g(x)$ appear as crossing points on the graphs of `f` and `g`, whereas they appear as zeros (crossings of the $x$-axis) when `h` is plotted.\n\n\nA different graph can be made to compare the two functions side-by-side. This is a parametric plot. Rather than plotting points $(x,f(x))$ and $(x,g(x))$ with two separate graphs, the graph consists of points $(f(x), g(x))$. We illustrate with some examples below:\n\n\n##### Example\n\n\nThe most \"famous\" parametric graph is one that is likely already familiar, as it follows the parametrization of points on the unit circle by the angle made between the $x$ axis and the ray from the origin through the point. (If not familiar, this will soon be discussed in these notes.)\n\n::: {.cell execution_count=31}\n``` {.julia .cell-code}\nš(x) = cos(x); š(x) = sin(x)\nšs = range(0, 2pi, length=100)\nplot(š.(šs), š.(šs), aspect_ratio=:equal) # make equal axes\n```\n\n::: {.cell-output .cell-output-display execution_count=31}\n{}\n:::\n:::\n\n\nAny point $(a,b)$ on this graph is represented by $(\\cos(t), \\sin(t))$ for some value of $t$, and in fact multiple values of $t$, since $t + 2k\\pi$ will produce the same $(a,b)$ value as $t$ will.\n\n\nMaking the parametric plot is similar to creating a plot using lower level commands. There a sequence of values is generated to approximate the $x$ values in the graph (`xs`), a set of commands to create the corresponding function values (e.g., `f.(xs)`), and some instruction on how to represent the values, in this case with lines connecting the points (the default for `plot` for two sets of numbers).\n\n\nIn this next plot, the angle values are chosen to be the familiar ones, so the mechanics of the graph can be emphasized. Only the upper half is plotted:\n\n::: {.cell hold='true' execution_count=32}\n\n::: {.cell-output .cell-output-display execution_count=32}\n```{=html}\n
9 rows Ć 3 columns
| Īø | x | y | |
|---|---|---|---|
| Sym | Sym | Sym | |
| 1 | 0 | 1 | 0 |
| 2 | pi/6 | sqrt(3)/2 | 1/2 |
| 3 | pi/4 | sqrt(2)/2 | sqrt(2)/2 |
| 4 | pi/3 | 1/2 | sqrt(3)/2 |
| 5 | pi/2 | 0 | 1 |
| 6 | 2*pi/3 | -1/2 | sqrt(3)/2 |
| 7 | 3*pi/4 | -sqrt(2)/2 | sqrt(2)/2 |
| 8 | 5*pi/6 | -sqrt(3)/2 | 1/2 |
| 9 | pi | -1 | 0 |