updates
This commit is contained in:
@@ -15,6 +15,7 @@ using SymPy
|
||||
using Roots
|
||||
using QuadGK
|
||||
using JSON
|
||||
using ScatteredInterpolation
|
||||
```
|
||||
|
||||
Also, these methods from the `Contour` package:
|
||||
@@ -173,7 +174,7 @@ surface(xs, ys, 𝒇)
|
||||
The `surface` function will generate the surface.
|
||||
|
||||
|
||||
:::{.callout-note}
|
||||
::: {.callout-note}
|
||||
## Note
|
||||
Using `surface` as a function name is equivalent to `plot(xs, ys, f, seriestype=:surface)`.
|
||||
|
||||
@@ -524,12 +525,97 @@ The filled contour layers on the contour lines to a heatmap:
|
||||
```{julia}
|
||||
#| hold: true
|
||||
f(x,y) = exp(-(x^2 + y^2)/5) * sin(x) * cos(y)
|
||||
xs= ys = range(-pi, pi, length=100)
|
||||
xs = ys = range(-pi, pi, length=100)
|
||||
contourf(xs, ys, f)
|
||||
```
|
||||
|
||||
This function has a prominent peak and a prominent valley, around the middle of the viewing window. The nested contour lines indicate this, and the color key can be used to identify which is the peak and which the valley.
|
||||
|
||||
##### Example
|
||||
|
||||
The description of a function for the contour function is in terms of a grid of $x-y$ values and a function $f$ which gives the height, $z$. In other situations, it might make more sense to have a stream of $x-y-z$ values describing a surface. This might be the case, say, with trying to piece together a topography using a series of GPS track. To do so, one way is to take a regular grid of points and then *interpolate* $z$ values from the existing values.
|
||||
|
||||
The `ScatteredInterpolation.jl` package can be used to create a structure that can be used to interpolate points. The necessary pieces are the points, the sampled heights, and a method for the interpolation.
|
||||
|
||||
|
||||
A simple example follows (inspired by a [discourse post](https://discourse.julialang.org/t/plots-contourf-and-plotlyjs-contour-behaviour-with-regard-to-the-x-y-z-input/122897/2)) where the true surface is known so that a comparison can be made is given. The two figures show the contour described by 4 paths through the space, is not as detailed but captures the general shape reasonably well.
|
||||
|
||||
```{julia}
|
||||
f(x,y) = 3*(1-x)^2*exp(-(x^2) - (y+1)^2) -
|
||||
10*(x/5 - x^3 - y^5)*exp(-x^2-y^2) -
|
||||
1/3*exp(-(x+1)^2 - y^2)
|
||||
|
||||
r(t, a=2) = [a*cbrt(sinpi(t)), a * cbrt(cospi(t))]
|
||||
ts = range(0, 2, 30)[1:end-1]
|
||||
pts = vcat([[r(t,a) for t in ts] for a in [1/2, 1, 3/2, 2]]...)
|
||||
samples = [f(pt...) for pt in pts]
|
||||
first(zip(pts, samples),5)
|
||||
```
|
||||
|
||||
```{julia}
|
||||
using ScatteredInterpolation
|
||||
itp = interpolate(Multiquadratic(), stack(pts), samples)
|
||||
|
||||
# make a grid
|
||||
(xm,xM), (ym,yM) = extrema.(eachrow(stack(pts)))
|
||||
n, m = 25, 40
|
||||
xg, yg = range(xm,xM,n), range(ym, yM, m)
|
||||
X = [s for t in yg, s in xg] #size(X) is (m,n)
|
||||
Y = [t for t in yg, s in xg] # size(Y) is also (m,n)
|
||||
gridP = stack(vec([[x, y] for (x,y) in zip(X, Y)]))
|
||||
gridP = stack(vec([[x, y] for (x,y) in zip(X, Y)])) #2 x m*n - matrix; each column is a grid point
|
||||
interpolated = evaluate(itp, gridP)
|
||||
zg = reshape(interpolated, m, n)
|
||||
|
||||
p = Plots.contourf(xg, yg, zg; levels=6)
|
||||
q = Plots.contourf(xg, yg, f)
|
||||
plot(p,q)
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
```{julia}
|
||||
using Plots
|
||||
```
|
||||
##### Example
|
||||
|
||||
The arrangement of the data in a heatmap or contour plot depends on the underlying plotting package. A [discourse post](https://discourse.julialang.org/t/wrong-heatmap-orientation-with-plots-jl/124822/9) used this example to illustrate.
|
||||
|
||||
The data is a matrix
|
||||
|
||||
```{julia}
|
||||
xy = [1 2; 3 4]
|
||||
```
|
||||
|
||||
which has these colors mapped to their values:
|
||||
|
||||
```{julia}
|
||||
cmap =[:red, :green, :blue, :orange]
|
||||
cmap[xy]
|
||||
```
|
||||
|
||||
@fig-plots-makie-heatmap shows on the left the image created by this command in `Plots`, and on the right the image created with the same command using `Makie`:
|
||||
|
||||
|
||||
|
||||
```{julia}
|
||||
#| eval: false
|
||||
heatmap(xy; colormap = cols, title="Plots", legend=false)
|
||||
```
|
||||
|
||||
```{julia}
|
||||
#| echo: false
|
||||
#| layout-ncol: 2
|
||||
#| label: fig-plots-makie-heatmap
|
||||
#| fig-cap: "Orientation of heatmap may vary by plotting package."
|
||||
p = heatmap(xy; colormap = cmap, title="Plots",
|
||||
legend=false)
|
||||
q = heatmap(xy'; colormap = cmap, title="Makie",
|
||||
legend=false)
|
||||
plot(p,q,layout=(1,2))
|
||||
```
|
||||
|
||||
`Makie` uses the first dimension for `x` and the second for `y` (the first dimension is down the columns, then across); and `Plots` plots `x` values on the `x` axis etc. with values rising upwards and towards the left.
|
||||
|
||||
## Limits
|
||||
|
||||
@@ -785,7 +871,7 @@ Another alternative would be to hold one variable constant, and use the `derivat
|
||||
partial_x(f, y) = x -> ForwardDiff.derivative(u -> f(u,y), x)
|
||||
```
|
||||
|
||||
:::{.callout-note}
|
||||
::: {.callout-note}
|
||||
## Note
|
||||
For vector-valued functions, we can override the syntax `'` using `Base.adjoint`, as `'` is treated as a postfix operator in `Julia` for the `adjoint` operation. The symbol `\\nabla` is also available in `Julia`, but it is not an operator, so can't be used as mathematically written `∇f` (this could be used as a name though). In `CalculusWithJulia` a definition is made so essentially `∇(f) = x -> ForwardDiff.gradient(f, x)`. It does require parentheses to be called, as in `∇(f)`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user