pub struct LineOpts { /* private fields */ }Expand description
Per-call options for Figure::line.
Implementations§
Source§impl LineOpts
impl LineOpts
Sourcepub fn label(self, s: impl Into<String>) -> Self
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
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}Additional examples can be found in:
Sourcepub fn stroke(self, s: Stroke) -> Self
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
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}Additional examples can be found in:
pub fn stroke_width(self, w: f64) -> Self
pub fn markers(self) -> Self
Sourcepub fn marker(self, m: Marker) -> Self
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}pub fn marker_size(self, sz: f64) -> Self
Trait Implementations§
Auto Trait Implementations§
impl Freeze for LineOpts
impl RefUnwindSafe for LineOpts
impl Send for LineOpts
impl Sync for LineOpts
impl Unpin for LineOpts
impl UnsafeUnpin for LineOpts
impl UnwindSafe for LineOpts
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more