Skip to content

Commit

Permalink
merge the 3d feature
Browse files Browse the repository at this point in the history
  • Loading branch information
38 committed Sep 3, 2020
1 parent af14084 commit 8b10487
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 54 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ This is the next major release of Plotters, see [release notes](./RELEASE-NOTES.
- Linspace coordinate type, which allows define a discrete coordinate on continous value types (such as f32, DateTime, etc) with a step specification
- Nested coordinate type, now we support define pair of category and nested values as nested coordinate.
- Introduce backend crates: plotters-bitmap, plotters-svg, plotters-cairo, plotters-canvas, plotters-console
- 3D Plotting features

### Fixed

- Adjust Canvas backend size with DPR (Thanks to Marius-Mueller)
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ To view the source code for each example, please click on the example image.
<img src="https://plotters-rs.github.io/plotters-doc-data/boxplot.svg" class="galleryItem" width=200px></img>
</a>

<a href="https://github.com/38/plotters/blob/master/examples/3d-plot.rs">
<img src="https://plotters-rs.github.io/plotters-doc-data/3d-plot.svg" class="galleryItem" width=200px></img>
</a>


## Table of Contents
* [Gallery](#gallery)
Expand Down Expand Up @@ -416,7 +420,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.x_label_area_size(20)
.y_label_area_size(40)
// Finally attach a coordinate on the drawing area and make a chart context
.build_ranged(0f32..10f32, 0f32..10f32)?;
.build_cartesian_2d(0f32..10f32, 0f32..10f32)?;

// Then we can draw a mesh
chart
Expand Down
1 change: 1 addition & 0 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,6 @@ Plotters 0.3 ships with tons of improvement made in the coordinate abstraction a
* Linspace coordinate, which can be used converting a continous coorindate into a discrete buckets
* Nested coordinate
* Slices can now be used as cooradnite specification, which allows people define an axis of category.
* 3D Coordinate is now supported

## Fix bugs and improve testing
2 changes: 1 addition & 1 deletion doc-template/examples/chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.x_label_area_size(20)
.y_label_area_size(40)
// Finally attach a coordinate on the drawing area and make a chart context
.build_ranged(0f32..10f32, 0f32..10f32)?;
.build_cartesian_2d(0f32..10f32, 0f32..10f32)?;

// Then we can draw a mesh
chart
Expand Down
4 changes: 4 additions & 0 deletions doc-template/readme/gallery
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,7 @@ To view the source code for each example, please click on the example image.
<a href="https://github.com/38/plotters/blob/master/examples/boxplot.rs">
<img src="https://plotters-rs.github.io/plotters-doc-data/boxplot.svg" class="galleryItem" width=200px></img>
</a>

<a href="https://github.com/38/plotters/blob/master/examples/3d-plot.rs">
<img src="https://plotters-rs.github.io/plotters-doc-data/3d-plot.svg" class="galleryItem" width=200px></img>
</a>
2 changes: 1 addition & 1 deletion examples/chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.margin(5)
.set_all_label_area_size(50)
.caption("Sine and Cosine", ("sans-serif", 40).into_font())
.build_cartesian_2d(x_axis.clone(), -1.2f32..1.2f32)?;
.build_cartesian_2d(-3.4f32..3.4, -1.2f32..1.2f32)?;

cc.configure_mesh()
.x_labels(20)
Expand Down
2 changes: 1 addition & 1 deletion plotters-doc-data
14 changes: 12 additions & 2 deletions src/coord/ranged1d/types/numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,12 @@ make_numeric_coord!(
impl_reverse_mapping_trait!(f32, RangedCoordf32);
impl ValueFormatter<f32> for RangedCoordf32 {
fn format(value: &f32) -> String {
crate::data::float::pretty_print_float(*value as f64, false)
crate::data::float::FloatPrettyPrinter {
allow_scientific: false,
min_decimal: 1,
max_decimal: 5,
}
.print(*value as f64)
}
}
make_numeric_coord!(
Expand All @@ -230,7 +235,12 @@ make_numeric_coord!(
impl_reverse_mapping_trait!(f64, RangedCoordf64);
impl ValueFormatter<f64> for RangedCoordf64 {
fn format(value: &f64) -> String {
crate::data::float::pretty_print_float(*value, false)
crate::data::float::FloatPrettyPrinter {
allow_scientific: false,
min_decimal: 1,
max_decimal: 5,
}
.print(*value)
}
}
make_numeric_coord!(
Expand Down
130 changes: 83 additions & 47 deletions src/data/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,91 @@ fn find_minimal_repr(n: f64, eps: f64) -> (f64, usize) {
}
}

fn float_to_string(n: f64, max_precision: usize) -> String {
let (sign, n) = if n < 0.0 { ("-", -n) } else { ("", n) };
let int_part = n.floor();
fn float_to_string(n: f64, max_precision: usize, min_decimal: usize) -> String {
let (mut result, mut count) = loop {
let (sign, n) = if n < 0.0 { ("-", -n) } else { ("", n) };
let int_part = n.floor();

let dec_part =
((n.abs() - int_part.abs()) * (10.0f64).powf(max_precision as f64)).round() as u64;
let dec_part =
((n.abs() - int_part.abs()) * (10.0f64).powi(max_precision as i32)).round() as u64;

if dec_part == 0 || max_precision == 0 {
return format!("{}{:.0}", sign, int_part);
}
if dec_part == 0 || max_precision == 0 {
break (format!("{}{:.0}", sign, int_part), 0);
}

let mut leading = "".to_string();
let mut dec_result = format!("{}", dec_part);
let mut leading = "".to_string();
let mut dec_result = format!("{}", dec_part);

for _ in 0..(max_precision - dec_result.len()) {
leading.push('0');
}
for _ in 0..(max_precision - dec_result.len()) {
leading.push('0');
}

while let Some(c) = dec_result.pop() {
if c != '0' {
dec_result.push(c);
break;
while let Some(c) = dec_result.pop() {
if c != '0' {
dec_result.push(c);
break;
}
}

break (
format!("{}{:.0}.{}{}", sign, int_part, leading, dec_result),
leading.len() + dec_result.len(),
);
};

if count == 0 && min_decimal > 0 {
result.push('.');
}

while count < min_decimal {
result.push('0');
count += 1;
}
result
}

pub struct FloatPrettyPrinter {
pub allow_scientific: bool,
pub min_decimal: i32,
pub max_decimal: i32,
}

impl FloatPrettyPrinter {
pub fn print(&self, n: f64) -> String {
let (n, p) = find_minimal_repr(n, (10f64).powi(-self.max_decimal));
let d_repr = float_to_string(n, p, self.min_decimal as usize);
if !self.allow_scientific {
d_repr
} else {
if n == 0.0 {
return "0".to_string();
}

let mut idx = n.abs().log10().floor();
let mut exp = (10.0f64).powf(idx);

format!("{}{:.0}.{}{}", sign, int_part, leading, dec_result)
if n.abs() / exp + 1e-5 >= 10.0 {
idx += 1.0;
exp *= 10.0;
}

if idx.abs() < 3.0 {
return d_repr;
}

let (sn, sp) = find_minimal_repr(n / exp, 1e-5);
let s_repr = format!(
"{}e{}",
float_to_string(sn, sp, self.min_decimal as usize),
float_to_string(idx, 0, 0)
);
if s_repr.len() + 1 < d_repr.len() {
s_repr
} else {
d_repr
}
}
}
}

/// The function that pretty prints the floating number
Expand All @@ -50,35 +109,12 @@ fn float_to_string(n: f64, max_precision: usize) -> String {
/// - `allow_sn`: Should we use scientific notation when possible
/// - **returns**: The pretty printed string
pub fn pretty_print_float(n: f64, allow_sn: bool) -> String {
let (n, p) = find_minimal_repr(n, 1e-10);
let d_repr = float_to_string(n, p);
if !allow_sn {
d_repr
} else {
if n == 0.0 {
return "0".to_string();
}

let mut idx = n.abs().log10().floor();
let mut exp = (10.0f64).powf(idx);

if n.abs() / exp + 1e-5 >= 10.0 {
idx += 1.0;
exp *= 10.0;
}

if idx.abs() < 3.0 {
return d_repr;
}

let (sn, sp) = find_minimal_repr(n / exp, 1e-5);
let s_repr = format!("{}e{}", float_to_string(sn, sp), float_to_string(idx, 0));
if s_repr.len() + 1 < d_repr.len() {
s_repr
} else {
d_repr
}
}
(FloatPrettyPrinter {
allow_scientific: allow_sn,
min_decimal: 0,
max_decimal: 10,
})
.print(n)
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.x_label_area_size(20)
.y_label_area_size(40)
// Finally attach a coordinate on the drawing area and make a chart context
.build_ranged(0f32..10f32, 0f32..10f32)?;
.build_cartesian_2d(0f32..10f32, 0f32..10f32)?;
// Then we can draw a mesh
chart
Expand Down

0 comments on commit 8b10487

Please sign in to comment.