use plotters::prelude::*; fn pdf(x: f64, y: f64) -> f64 { const SDX: f64 = 0.1; const SDY: f64 = 0.1; const A: f64 = 5.0; let x = x / 10.0; let y = y / 10.0; A * (-x * x / 2.0 / SDX / SDX - y * y / 2.0 / SDY / SDY).exp() } const OUT_FILE_NAME: &str = "plotters-doc-data/3d-plot2.gif"; fn main() -> Result<(), Box> { let root = BitMapBackend::gif(OUT_FILE_NAME, (600, 400), 100)?.into_drawing_area(); for pitch in 0..157 { root.fill(&WHITE)?; let mut chart = ChartBuilder::on(&root) .caption("2D Gaussian PDF", ("sans-serif", 20)) .build_cartesian_3d(-3.0..3.0, 0.0..6.0, -3.0..3.0)?; chart.with_projection(|mut p| { p.pitch = 1.57 - (1.57 - pitch as f64 / 50.0).abs(); p.scale = 0.7; p.into_matrix() // build the projection matrix }); chart .configure_axes() .light_grid_style(BLACK.mix(0.15)) .max_light_lines(3) .draw()?; chart.draw_series( SurfaceSeries::xoz( (-15..=15).map(|x| x as f64 / 5.0), (-15..=15).map(|x| x as f64 / 5.0), pdf, ) .style_func(&|&v| (VulcanoHSL::get_color(v / 5.0)).into()), )?; root.present()?; } // To avoid the IO failure being ignored silently, we manually call the present function root.present().expect("Unable to write result to file, please make sure 'plotters-doc-data' dir exists under current dir"); println!("Result has been saved to {}", OUT_FILE_NAME); Ok(()) } #[test] fn entry_point() { main().unwrap() }