-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
plot: Add predefined tick formatters
- Loading branch information
1 parent
5e568f5
commit 2f32249
Showing
9 changed files
with
196 additions
and
40 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,39 @@ | ||
#import "@preview/cetz:0.2.2": canvas | ||
#import "@preview/cetz:0.2.2": canvas, draw | ||
#import "@preview/cetz-plot:0.1.0": plot | ||
|
||
#set page(width: auto, height: auto, margin: .5cm) | ||
|
||
#let style = (stroke: black, fill: rgb(0, 0, 200, 75)) | ||
|
||
#canvas(length: 1cm, { | ||
plot.plot(size: (8, 6), | ||
x-tick-step: none, | ||
x-ticks: ((-calc.pi, $-pi$), (0, $0$), (calc.pi, $pi$)), | ||
y-tick-step: 1, | ||
#let f1(x) = calc.sin(x) | ||
#let fn = ( | ||
($ x - x^3"/"3! $, x => x - calc.pow(x, 3)/6), | ||
($ x - x^3"/"3! - x^5"/"5! $, x => x - calc.pow(x, 3)/6 + calc.pow(x, 5)/120), | ||
($ x - x^3"/"3! - x^5"/"5! - x^7"/"7! $, x => x - calc.pow(x, 3)/6 + calc.pow(x, 5)/120 - calc.pow(x, 7)/5040), | ||
) | ||
|
||
#set text(size: 10pt) | ||
|
||
#canvas({ | ||
import draw: * | ||
|
||
// Set-up a thin axis style | ||
set-style(axes: (stroke: .5pt, tick: (stroke: .5pt)), | ||
legend: (stroke: none, orientation: ttb, item: (spacing: .3), scale: 80%)) | ||
|
||
plot.plot(size: (12, 8), | ||
x-tick-step: calc.pi/2, | ||
x-format: plot.formats.multiple-of, | ||
y-tick-step: 2, y-min: -2.5, y-max: 2.5, | ||
legend: "inner-north", | ||
{ | ||
plot.add( | ||
style: style, | ||
domain: (-calc.pi, calc.pi), calc.sin) | ||
plot.add( | ||
hypograph: true, | ||
style: style, | ||
domain: (-calc.pi, calc.pi), calc.cos) | ||
plot.add( | ||
hypograph: true, | ||
style: style, | ||
domain: (-calc.pi, calc.pi), x => calc.cos(x + calc.pi)) | ||
let domain = (-1.1 * calc.pi, +1.1 * calc.pi) | ||
|
||
for ((title, f)) in fn { | ||
plot.add-fill-between(f, f1, domain: domain, | ||
style: (stroke: none), label: title) | ||
} | ||
plot.add(f1, domain: domain, label: $ sin x $, | ||
style: (stroke: black)) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Compare two floats | ||
#let _compare(a, b, eps: 1e-6) = { | ||
return calc.abs(a - b) <= eps | ||
} | ||
|
||
// Pre-computed table of fractions | ||
#let _common-denoms = range(2, 11 + 1).map(d => { | ||
(d, range(1, d).map(n => n/d)) | ||
}) | ||
|
||
#let _find-fraction(v, denom: auto, eps: 1e-6) = { | ||
let i = calc.floor(v) | ||
let f = v - i | ||
if _compare(f, 0, eps: eps) { | ||
return $#v$ | ||
} | ||
|
||
let denom = if denom != auto { | ||
for n in range(1, denom) { | ||
if _compare(f, n/denom, eps: eps) { | ||
denom | ||
} | ||
} | ||
} else { | ||
(() => { | ||
for ((denom, tab)) in _common-denoms { | ||
for vv in tab { | ||
if _compare(f, vv, eps: eps) { | ||
return denom | ||
} | ||
} | ||
} | ||
})() | ||
} | ||
|
||
if denom != none { | ||
return if v < 0 { $-$ } else {} + $#calc.round(calc.abs(v) * denom)/#denom$ | ||
} | ||
} | ||
|
||
/// Fraction tick formatter | ||
/// | ||
/// - value (number): Value to format | ||
/// - denom (auto, int): Denominator for result fractions. If set to `auto`, | ||
/// a hardcoded fraction table is used for finding fractions with a | ||
/// denominator <= 11. | ||
/// - eps (number): Epsilon used for comparison | ||
/// -> Content if a matching fraction could be found or none | ||
#let fraction(value, denom: auto, eps: 1e-6) = { | ||
return _find-fraction(value, denom: denom, eps: eps) | ||
} | ||
|
||
/// Multiple of tick formatter | ||
/// | ||
/// ```example | ||
/// plot.plot(x-format: plot.formats.multiple-of, | ||
/// x-tick-step: calc.pi/4, { | ||
/// plot.add(calc.sin, domain: (-calc.pi, 1.5 * calc.pi)) | ||
/// }) | ||
/// ``` | ||
/// | ||
/// - value (number): Value to format | ||
/// - factor (number): Factor value is expected to be a multiple of. | ||
/// - symbol (content): Suffix symbol. For `value` = 0, the symbol is not | ||
/// appended. | ||
/// - fraction (none, true, int): If not none, try finding matching fractions | ||
/// using the same mechanism as `fraction`. If set to an integer, that integer | ||
/// is used as denominator. If set to `none` or `false`, or if no fraction | ||
/// could be found, a real number with `digits` digits is used. | ||
/// - digits (int): Number of digits to use for rounding | ||
/// - eps (number): Epsilon used for comparison | ||
/// -> Content if a matching fraction could be found or none | ||
#let multiple-of(value, factor: calc.pi, symbol: $pi$, fraction: true, digits: 2, eps: 1e-6) = { | ||
if _compare(value, 0, eps: eps) { | ||
return $0$ | ||
} | ||
|
||
let a = value / factor | ||
if _compare(a, 1, eps: eps) { | ||
return symbol | ||
} else if _compare(a, -1, eps: eps) { | ||
return $-$ + symbol | ||
} | ||
|
||
if fraction != none { | ||
let frac = _find-fraction(a, denom: if fraction == true { auto } else { fraction }) | ||
if frac != none { | ||
return frac + symbol | ||
} | ||
} | ||
|
||
return $#calc.round(a, digits: digits)$ + symbol | ||
} | ||
|
||
/// Scientific notation tick formatter | ||
/// | ||
/// - value (number): Value to format | ||
/// - digits (int): Number of digits for rouding the factor | ||
/// -> Content | ||
#let sci(value, digits: 2) = { | ||
let exponent = if value != 0 { | ||
calc.floor(calc.log(calc.abs(value), base: 10)) | ||
} else { | ||
0 | ||
} | ||
|
||
let ee = calc.pow(10, calc.abs(exponent + 1)) | ||
if exponent > 0 { | ||
value = value / ee * 10 | ||
} else if exponent < 0 { | ||
value = value * ee * 10 | ||
} | ||
|
||
value = calc.round(value, digits: digits) | ||
if exponent <= -1 or exponent >= 1 { | ||
return $#value times 10^#exponent$ | ||
} | ||
return $#value$ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#set page(width: auto, height: auto) | ||
#import "/tests/helper.typ": * | ||
#import cetz: draw | ||
#import cetz-plot: plot | ||
|
||
#let data = ((-calc.pi, -1), (+calc.pi, +1)) | ||
|
||
#test-case({ | ||
plot.plot( | ||
size: (8, 4), | ||
x-min: -2 * calc.pi, | ||
x-max: +2 * calc.pi, | ||
x-tick-step: calc.pi/2, | ||
x-format: plot.formats.multiple-of, { | ||
plot.add(data) | ||
}) | ||
}) | ||
|
||
#test-case({ | ||
plot.plot( | ||
size: (8, 4), | ||
x-min: -2, | ||
x-max: +2, | ||
x-tick-step: 1/3, | ||
x-format: plot.formats.fraction, { | ||
plot.add(data) | ||
}) | ||
}) | ||
|
||
#test-case({ | ||
plot.plot( | ||
size: (8, 4), | ||
x-min: -2, | ||
x-max: +2, | ||
x-tick-step: 1/3, | ||
x-format: plot.formats.fraction.with(denom: 33), { | ||
plot.add(data) | ||
}) | ||
}) |