Beginner 3
Mix.install([
{:vega_lite, "~> 0.1.10"},
{:kino_vega_lite, "~> 0.1.13"}
])
Forberedelse
På denne side skal vi arbejde med anonyme funktioner. En funktion er et stykke kode der tager nul eller flere input og levere et output.
Følgende funktion tager netop ét input og leverer dette som sit output:
fn input -> input end
Bemærk: Elixir fortæller os at denne ene linje evaluerer til en funktion. Lad os prøve at sætte en variabel lig med denne funktion:
pipethrough = fn input -> input end
Herefter kan vi prøve at kalde den med en værdi:
pipethrough.(42)
Og ganske rigtigt: Input blev til output
Vi kan også definere en funktion der repræsenterer den matematiske funktion $f(x) = 1.2x^2-1.3x+0.9$:
f = fn x -> 1.2*x*x - 1.3*x + 0.9 end
Nu kan vi eksempelvis udregne $f(10)$:
f.(10)
Vi kan nu tage en sekvens af $x$-værdier og udregne de matchende $f(x)$-værdier, og konvertere hver matchende kombination som et map (jeg forventer ikke at du forstår denne kode):
data =
-10..10
|> Enum.map(fn x -> %{"x" => x, "f(x)" => f.(x)} end)
Vi kan bruge VegaLite til at plotte disse data. Af bekvemmelighedsgrunde lægger vi ud med at lave et Vl
alias så vi ikke behøver at skrive VegaLite
hele tiden:
alias VegaLite, as: Vl
Derefter kan vi plotte:
Vl.new(width: 400, height: 300)
|> Vl.data_from_values(data)
|> Vl.mark(:point)
|> Vl.encode_field(:x, "x", type: :quantitative)
|> Vl.encode_field(:y, "f(x)", type: :quantitative)
Øvelse
Implementer en circumference
funktion, der givet en radius på en cirkel udregner denne cirkels omkreds:
Vælg en mindste og en største interessante radius, og producér et dataset i variablen data_circumference
som er klar til at blive plottet:
Plot disse data:
Hold nu musen over den sidste Vl.encode_field
linje indtil du ser en popup. Heri finder du et View on Hexdocs
link. Åben dette link i en ny tab og find ud af hvordan man kan definere en tittel for en akse.
Lav en kopi af forrige celle herunder, og opdater denne med navne for de to akser.
Næste trin …
En af ovenstående celler så sådan her ud:
data =
-10..10
|> Enum.map(fn x -> %{"x" => x, "f(x)" => f.(x)} end)
Hvad betyder det egentligt? Det finder vi ud af her.