Skip to main content

LineOpts

Struct LineOpts 

Source
pub struct LineOpts { /* private fields */ }
Expand description

Per-call options for Figure::line.

Implementations§

Source§

impl LineOpts

Source

pub fn label(self, s: impl Into<String>) -> Self

Examples found in repository?
examples/gen_hero_svgs.rs (line 57)
47fn oscillation() -> String {
48    let xs: Vec<f64> = (0..=200).map(|i| i as f64 / 20.0).collect();
49    let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
50    let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();
51
52    Figure::new()
53        .size(PaperSize::A5Landscape)
54        .title("Damped oscillation")
55        .xlabel("t [s]")
56        .ylabel("x(t)")
57        .line(&xs, &response, |s| s.label("response"))
58        .line(&xs, &envelope, |s| s.label("envelope").stroke(Stroke::Dashed))
59        .hline(0.0, |s| s.stroke(Stroke::Dotted))
60        .legend_top_right()
61        .to_svg()
62}
63
64fn histogram() -> String {
65    let samples: Vec<f64> = (0..2000)
66        .map(|i| {
67            let u1 = ((i as f64 * 0.732 + 0.31) % 1.0).max(1e-9);
68            let u2 = (i as f64 * 1.197 + 0.71) % 1.0;
69            (-2.0 * u1.ln()).sqrt() * (2.0 * std::f64::consts::PI * u2).cos()
70        })
71        .collect();
72
73    Figure::new()
74        .size(PaperSize::A5Landscape)
75        .title("Standard normal — 2000 samples")
76        .xlabel("z")
77        .ylabel("density")
78        .histogram(&samples, |h| {
79            h.bins(40)
80                .normalize(Normalize::Density)
81                .hatch(Hatch::Diagonal)
82                .label("samples")
83        })
84        .legend_top_right()
85        .to_svg()
86}
87
88fn bar() -> String {
89    let cats = ["A", "B", "C", "D"];
90    Figure::new()
91        .size(PaperSize::A5Landscape)
92        .title("Test bench results")
93        .xlabel("specimen")
94        .ylabel("yield (MPa)")
95        .bar(&cats, &[320.0, 290.0, 410.0, 355.0], |b| {
96            b.label("trial 1").hatch(Hatch::Diagonal).group(0)
97        })
98        .bar(&cats, &[345.0, 305.0, 395.0, 380.0], |b| {
99            b.label("trial 2").hatch(Hatch::Crosshatch).group(1)
100        })
101        .legend_top_left()
102        .to_svg()
103}
104
105fn heatmap() -> String {
106    let n = 30;
107    let grid: Vec<Vec<f64>> = (0..n)
108        .map(|j| {
109            let y = -2.0 + 4.0 * j as f64 / (n - 1) as f64;
110            (0..n)
111                .map(|i| {
112                    let x = -2.0 + 4.0 * i as f64 / (n - 1) as f64;
113                    (-(x * x + y * y) / 0.6).exp()
114                })
115                .collect()
116        })
117        .collect();
118    let edges: Vec<f64> = (0..=n).map(|i| -2.0 + 4.0 * i as f64 / n as f64).collect();
119
120    Figure::new()
121        .size(PaperSize::Square)
122        .title("2D Gaussian density")
123        .xlabel("x")
124        .ylabel("y")
125        .heatmap(grid, |h| {
126            h.x_edges(edges.clone())
127                .y_edges(edges.clone())
128                .label("density")
129        })
130        .colorbar(ColorbarPosition::Right)
131        .to_svg()
132}
133
134fn polar() -> String {
135    let n = 200;
136    let thetas: Vec<f64> = (0..=n)
137        .map(|i| i as f64 / n as f64 * std::f64::consts::TAU)
138        .collect();
139    let cardioid: Vec<f64> = thetas.iter().map(|t| 1.0 + t.cos()).collect();
140    let rose: Vec<f64> = thetas.iter().map(|t| (3.0 * t).cos().abs() * 1.5).collect();
141
142    Figure::polar(2.1)
143        .title("Polar plots")
144        .polar_grid(PolarGridOpts::default())
145        .line(&thetas, &cardioid, |s| s.label("r = 1 + cos θ"))
146        .line(&thetas, &rose, |s| {
147            s.label("r = |cos 3θ|").stroke(Stroke::Dashed)
148        })
149        .legend_bottom_left()
150        .to_svg()
151}
152
153fn smith() -> String {
154    let n = 60;
155    let mut grs = Vec::with_capacity(n);
156    let mut gis = Vec::with_capacity(n);
157    for i in 0..n {
158        let f = i as f64 / (n - 1) as f64;
159        let r = 0.4 + 1.6 * f;
160        let x = -1.5 + 3.0 * f;
161        let (gr, gi) = bland::gamma_from_z(r, x);
162        grs.push(gr);
163        gis.push(gi);
164    }
165
166    Figure::smith()
167        .title("S₁₁ sweep")
168        .smith_grid(bland::SmithGridOpts::default())
169        .line(&grs, &gis, |s| s.label("Γ(f)"))
170        .legend_bottom_right()
171        .to_svg()
172}
More examples
Hide additional examples
examples/smith.rs (line 21)
3fn main() {
4    // Sample S11 sweep: a frequency-dependent impedance Z(f) = R(f) + jX(f),
5    // converted to Γ.
6    let n = 60;
7    let mut grs = Vec::with_capacity(n);
8    let mut gis = Vec::with_capacity(n);
9    for i in 0..n {
10        let f = i as f64 / (n - 1) as f64;
11        let r = 0.4 + 1.6 * f;
12        let x = -1.5 + 3.0 * f;
13        let (gr, gi) = gamma_from_z(r, x);
14        grs.push(gr);
15        gis.push(gi);
16    }
17
18    let fig = Figure::smith()
19        .title("S₁₁ sweep")
20        .smith_grid(SmithGridOpts::default())
21        .line(&grs, &gis, |s| s.label("Γ(f)").stroke(Stroke::Solid))
22        .legend_bottom_right();
23
24    std::fs::create_dir_all("out").expect("create out/");
25    std::fs::write("out/smith.svg", fig.to_svg()).expect("write svg");
26    println!("wrote out/smith.svg");
27}
examples/polar.rs (line 17)
3fn main() {
4    // Cardioid: r = 1 + cos(θ).
5    let n = 200;
6    let thetas: Vec<f64> = (0..=n)
7        .map(|i| i as f64 / n as f64 * std::f64::consts::TAU)
8        .collect();
9    let rs: Vec<f64> = thetas.iter().map(|t| 1.0 + t.cos()).collect();
10
11    // |cos 3θ| rose for comparison.
12    let rose: Vec<f64> = thetas.iter().map(|t| (3.0 * t).cos().abs() * 1.5).collect();
13
14    let fig = Figure::polar(2.1)
15        .title("Polar plots")
16        .polar_grid(PolarGridOpts::default())
17        .line(&thetas, &rs, |s| s.label("r = 1 + cos θ").stroke(Stroke::Solid))
18        .line(&thetas, &rose, |s| {
19            s.label("r = |cos 3θ|").stroke(Stroke::Dashed)
20        })
21        .legend_bottom_left();
22
23    std::fs::create_dir_all("out").expect("create out/");
24    std::fs::write("out/polar.svg", fig.to_svg()).expect("write svg");
25    println!("wrote out/polar.svg");
26}
examples/show_demo.rs (line 19)
9fn main() {
10    let xs: Vec<f64> = (0..=200).map(|i| i as f64 / 20.0).collect();
11    let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
12    let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();
13
14    Figure::new()
15        .size(PaperSize::A5Landscape)
16        .title("Damped oscillation")
17        .xlabel("t [s]")
18        .ylabel("x(t)")
19        .line(&xs, &response, |s| s.label("response"))
20        .line(&xs, &envelope, |s| s.label("envelope").stroke(Stroke::Dashed))
21        .hline(0.0, |s| s.stroke(Stroke::Dotted))
22        .legend_top_right()
23        .title_block(
24            TitleBlock::new()
25                .project("BLAND Reference")
26                .title("Fig. 1 · Damped oscillation")
27                .drawn_by("JM")
28                .date("2026-04-29")
29                .scale("1:1")
30                .sheet("1 of 1")
31                .rev("A"),
32        )
33        .show();
34}
examples/panels.rs (line 13)
3fn main() {
4    let xs: Vec<f64> = (0..=100).map(|i| i as f64 / 10.0).collect();
5    let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
6    let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();
7
8    let panel_a = Figure::new()
9        .dimensions(800.0, 500.0)
10        .title("Panel A — response")
11        .xlabel("t [s]")
12        .ylabel("x(t)")
13        .line(&xs, &response, |s| s.label("x(t)"));
14
15    let panel_b = Figure::new()
16        .dimensions(800.0, 500.0)
17        .title("Panel B — envelope")
18        .xlabel("t [s]")
19        .ylabel("|x(t)|")
20        .line(&xs, &envelope, |s| {
21            s.label("envelope").stroke(Stroke::Dashed).marker(Marker::CircleOpen)
22        });
23
24    let svg = multi_panel(
25        &[panel_a, panel_b],
26        PanelGridOpts::default()
27            .columns(2)
28            .cell_size(800.0, 500.0)
29            .title("Damped oscillation — overview"),
30    );
31
32    std::fs::create_dir_all("out").expect("create out/");
33    std::fs::write("out/panels.svg", svg).expect("write svg");
34    println!("wrote out/panels.svg");
35}
examples/damped_oscillation.rs (line 13)
3fn main() {
4    let xs: Vec<f64> = (0..=200).map(|i| i as f64 / 20.0).collect();
5    let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
6    let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();
7
8    let fig = Figure::new()
9        .size(PaperSize::A5Landscape)
10        .title("Damped oscillation")
11        .xlabel("t [s]")
12        .ylabel("x(t)")
13        .line(&xs, &response, |s| s.label("response"))
14        .line(&xs, &envelope, |s| s.label("envelope").stroke(Stroke::Dashed))
15        .hline(0.0, |s| s.stroke(Stroke::Dotted))
16        .legend_top_right()
17        .title_block(
18            TitleBlock::new()
19                .project("BLAND Reference")
20                .title("Fig. 1 · Damped oscillation")
21                .drawn_by("JM")
22                .date("2026-04-28")
23                .scale("1:1")
24                .sheet("1 of 1")
25                .rev("A"),
26        );
27
28    std::fs::create_dir_all("out").expect("create out/");
29    std::fs::write("out/damped_oscillation.svg", fig.to_svg()).expect("write svg");
30    println!("wrote out/damped_oscillation.svg");
31}
Source

pub fn stroke(self, s: Stroke) -> Self

Examples found in repository?
examples/gen_hero_svgs.rs (line 58)
47fn oscillation() -> String {
48    let xs: Vec<f64> = (0..=200).map(|i| i as f64 / 20.0).collect();
49    let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
50    let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();
51
52    Figure::new()
53        .size(PaperSize::A5Landscape)
54        .title("Damped oscillation")
55        .xlabel("t [s]")
56        .ylabel("x(t)")
57        .line(&xs, &response, |s| s.label("response"))
58        .line(&xs, &envelope, |s| s.label("envelope").stroke(Stroke::Dashed))
59        .hline(0.0, |s| s.stroke(Stroke::Dotted))
60        .legend_top_right()
61        .to_svg()
62}
63
64fn histogram() -> String {
65    let samples: Vec<f64> = (0..2000)
66        .map(|i| {
67            let u1 = ((i as f64 * 0.732 + 0.31) % 1.0).max(1e-9);
68            let u2 = (i as f64 * 1.197 + 0.71) % 1.0;
69            (-2.0 * u1.ln()).sqrt() * (2.0 * std::f64::consts::PI * u2).cos()
70        })
71        .collect();
72
73    Figure::new()
74        .size(PaperSize::A5Landscape)
75        .title("Standard normal — 2000 samples")
76        .xlabel("z")
77        .ylabel("density")
78        .histogram(&samples, |h| {
79            h.bins(40)
80                .normalize(Normalize::Density)
81                .hatch(Hatch::Diagonal)
82                .label("samples")
83        })
84        .legend_top_right()
85        .to_svg()
86}
87
88fn bar() -> String {
89    let cats = ["A", "B", "C", "D"];
90    Figure::new()
91        .size(PaperSize::A5Landscape)
92        .title("Test bench results")
93        .xlabel("specimen")
94        .ylabel("yield (MPa)")
95        .bar(&cats, &[320.0, 290.0, 410.0, 355.0], |b| {
96            b.label("trial 1").hatch(Hatch::Diagonal).group(0)
97        })
98        .bar(&cats, &[345.0, 305.0, 395.0, 380.0], |b| {
99            b.label("trial 2").hatch(Hatch::Crosshatch).group(1)
100        })
101        .legend_top_left()
102        .to_svg()
103}
104
105fn heatmap() -> String {
106    let n = 30;
107    let grid: Vec<Vec<f64>> = (0..n)
108        .map(|j| {
109            let y = -2.0 + 4.0 * j as f64 / (n - 1) as f64;
110            (0..n)
111                .map(|i| {
112                    let x = -2.0 + 4.0 * i as f64 / (n - 1) as f64;
113                    (-(x * x + y * y) / 0.6).exp()
114                })
115                .collect()
116        })
117        .collect();
118    let edges: Vec<f64> = (0..=n).map(|i| -2.0 + 4.0 * i as f64 / n as f64).collect();
119
120    Figure::new()
121        .size(PaperSize::Square)
122        .title("2D Gaussian density")
123        .xlabel("x")
124        .ylabel("y")
125        .heatmap(grid, |h| {
126            h.x_edges(edges.clone())
127                .y_edges(edges.clone())
128                .label("density")
129        })
130        .colorbar(ColorbarPosition::Right)
131        .to_svg()
132}
133
134fn polar() -> String {
135    let n = 200;
136    let thetas: Vec<f64> = (0..=n)
137        .map(|i| i as f64 / n as f64 * std::f64::consts::TAU)
138        .collect();
139    let cardioid: Vec<f64> = thetas.iter().map(|t| 1.0 + t.cos()).collect();
140    let rose: Vec<f64> = thetas.iter().map(|t| (3.0 * t).cos().abs() * 1.5).collect();
141
142    Figure::polar(2.1)
143        .title("Polar plots")
144        .polar_grid(PolarGridOpts::default())
145        .line(&thetas, &cardioid, |s| s.label("r = 1 + cos θ"))
146        .line(&thetas, &rose, |s| {
147            s.label("r = |cos 3θ|").stroke(Stroke::Dashed)
148        })
149        .legend_bottom_left()
150        .to_svg()
151}
More examples
Hide additional examples
examples/smith.rs (line 21)
3fn main() {
4    // Sample S11 sweep: a frequency-dependent impedance Z(f) = R(f) + jX(f),
5    // converted to Γ.
6    let n = 60;
7    let mut grs = Vec::with_capacity(n);
8    let mut gis = Vec::with_capacity(n);
9    for i in 0..n {
10        let f = i as f64 / (n - 1) as f64;
11        let r = 0.4 + 1.6 * f;
12        let x = -1.5 + 3.0 * f;
13        let (gr, gi) = gamma_from_z(r, x);
14        grs.push(gr);
15        gis.push(gi);
16    }
17
18    let fig = Figure::smith()
19        .title("S₁₁ sweep")
20        .smith_grid(SmithGridOpts::default())
21        .line(&grs, &gis, |s| s.label("Γ(f)").stroke(Stroke::Solid))
22        .legend_bottom_right();
23
24    std::fs::create_dir_all("out").expect("create out/");
25    std::fs::write("out/smith.svg", fig.to_svg()).expect("write svg");
26    println!("wrote out/smith.svg");
27}
examples/polar.rs (line 17)
3fn main() {
4    // Cardioid: r = 1 + cos(θ).
5    let n = 200;
6    let thetas: Vec<f64> = (0..=n)
7        .map(|i| i as f64 / n as f64 * std::f64::consts::TAU)
8        .collect();
9    let rs: Vec<f64> = thetas.iter().map(|t| 1.0 + t.cos()).collect();
10
11    // |cos 3θ| rose for comparison.
12    let rose: Vec<f64> = thetas.iter().map(|t| (3.0 * t).cos().abs() * 1.5).collect();
13
14    let fig = Figure::polar(2.1)
15        .title("Polar plots")
16        .polar_grid(PolarGridOpts::default())
17        .line(&thetas, &rs, |s| s.label("r = 1 + cos θ").stroke(Stroke::Solid))
18        .line(&thetas, &rose, |s| {
19            s.label("r = |cos 3θ|").stroke(Stroke::Dashed)
20        })
21        .legend_bottom_left();
22
23    std::fs::create_dir_all("out").expect("create out/");
24    std::fs::write("out/polar.svg", fig.to_svg()).expect("write svg");
25    println!("wrote out/polar.svg");
26}
examples/show_demo.rs (line 20)
9fn main() {
10    let xs: Vec<f64> = (0..=200).map(|i| i as f64 / 20.0).collect();
11    let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
12    let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();
13
14    Figure::new()
15        .size(PaperSize::A5Landscape)
16        .title("Damped oscillation")
17        .xlabel("t [s]")
18        .ylabel("x(t)")
19        .line(&xs, &response, |s| s.label("response"))
20        .line(&xs, &envelope, |s| s.label("envelope").stroke(Stroke::Dashed))
21        .hline(0.0, |s| s.stroke(Stroke::Dotted))
22        .legend_top_right()
23        .title_block(
24            TitleBlock::new()
25                .project("BLAND Reference")
26                .title("Fig. 1 · Damped oscillation")
27                .drawn_by("JM")
28                .date("2026-04-29")
29                .scale("1:1")
30                .sheet("1 of 1")
31                .rev("A"),
32        )
33        .show();
34}
examples/annotated.rs (line 20)
3fn main() {
4    let xs: Vec<f64> = (0..=200).map(|i| i as f64 / 20.0).collect();
5    let ys: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
6
7    // Find the global maximum.
8    let (idx, &peak_y) = ys
9        .iter()
10        .enumerate()
11        .max_by(|a, b| a.1.partial_cmp(b.1).unwrap())
12        .unwrap();
13    let peak_x = xs[idx];
14
15    let fig = Figure::new()
16        .size(PaperSize::A5Landscape)
17        .title("Annotated peak")
18        .xlabel("t [s]")
19        .ylabel("x(t)")
20        .line(&xs, &ys, |s| s.stroke(Stroke::Solid))
21        .annotate_arrow((peak_x + 1.0, peak_y - 0.4), (peak_x, peak_y))
22        .annotate_text(peak_x + 1.05, peak_y - 0.45, "global peak", TextAnchor::Start)
23        .hline(0.0, |h| h.stroke(Stroke::Dotted));
24
25    std::fs::create_dir_all("out").expect("create out/");
26    std::fs::write("out/annotated.svg", fig.to_svg()).expect("write svg");
27    println!("wrote out/annotated.svg");
28}
examples/panels.rs (line 21)
3fn main() {
4    let xs: Vec<f64> = (0..=100).map(|i| i as f64 / 10.0).collect();
5    let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
6    let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();
7
8    let panel_a = Figure::new()
9        .dimensions(800.0, 500.0)
10        .title("Panel A — response")
11        .xlabel("t [s]")
12        .ylabel("x(t)")
13        .line(&xs, &response, |s| s.label("x(t)"));
14
15    let panel_b = Figure::new()
16        .dimensions(800.0, 500.0)
17        .title("Panel B — envelope")
18        .xlabel("t [s]")
19        .ylabel("|x(t)|")
20        .line(&xs, &envelope, |s| {
21            s.label("envelope").stroke(Stroke::Dashed).marker(Marker::CircleOpen)
22        });
23
24    let svg = multi_panel(
25        &[panel_a, panel_b],
26        PanelGridOpts::default()
27            .columns(2)
28            .cell_size(800.0, 500.0)
29            .title("Damped oscillation — overview"),
30    );
31
32    std::fs::create_dir_all("out").expect("create out/");
33    std::fs::write("out/panels.svg", svg).expect("write svg");
34    println!("wrote out/panels.svg");
35}
Source

pub fn stroke_width(self, w: f64) -> Self

Source

pub fn markers(self) -> Self

Source

pub fn marker(self, m: Marker) -> Self

Examples found in repository?
examples/panels.rs (line 21)
3fn main() {
4    let xs: Vec<f64> = (0..=100).map(|i| i as f64 / 10.0).collect();
5    let response: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp() * t.cos()).collect();
6    let envelope: Vec<f64> = xs.iter().map(|t| (-t / 4.0).exp()).collect();
7
8    let panel_a = Figure::new()
9        .dimensions(800.0, 500.0)
10        .title("Panel A — response")
11        .xlabel("t [s]")
12        .ylabel("x(t)")
13        .line(&xs, &response, |s| s.label("x(t)"));
14
15    let panel_b = Figure::new()
16        .dimensions(800.0, 500.0)
17        .title("Panel B — envelope")
18        .xlabel("t [s]")
19        .ylabel("|x(t)|")
20        .line(&xs, &envelope, |s| {
21            s.label("envelope").stroke(Stroke::Dashed).marker(Marker::CircleOpen)
22        });
23
24    let svg = multi_panel(
25        &[panel_a, panel_b],
26        PanelGridOpts::default()
27            .columns(2)
28            .cell_size(800.0, 500.0)
29            .title("Damped oscillation — overview"),
30    );
31
32    std::fs::create_dir_all("out").expect("create out/");
33    std::fs::write("out/panels.svg", svg).expect("write svg");
34    println!("wrote out/panels.svg");
35}
Source

pub fn marker_size(self, sz: f64) -> Self

Trait Implementations§

Source§

impl Debug for LineOpts

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for LineOpts

Source§

fn default() -> LineOpts

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.