fn hash_u32(mut a: u32) -> u32 {
a = a.wrapping_add(0x7ed55d16).wrapping_add(a.rotate_left(12));
a = (a ^ 0xc761c23c) ^ a.rotate_right(19);
a = a.wrapping_add(0x165667b1).wrapping_add(a.rotate_left(5));
a = a.wrapping_add(0xd3a2646c) ^ a.rotate_left(9);
a = a.wrapping_add(0xfd7046c5).wrapping_add(a.rotate_left(3));
a = (a ^ 0xb55a4f09) ^ a.rotate_right(16);
return a;
}
//lets do it with f64s for convenience
let mut random_points: Vec<[f64;2]> = vec![];
let number_points = 300;
let max_dimension = 1000;
for i in 0..number_points{
let i = hash_u32(i);
//convert x,y to percentage values [0.0, 1.0]
let x = (hash_u32(i)%max_dimension) as f64/max_dimension as f64;
let y = (hash_u32(hash_u32(i))%max_dimension) as f64/max_dimension as f64;
random_points.push([x, y]);
}
()
:dep plotters = { version = "^0.3.0", default_features = false, features = ["evcxr", "all_series"] }
//from https://plotters-rs.github.io/plotters-doc-data/evcxr-jupyter-integration.html
extern crate plotters;
use plotters::prelude::*;
evcxr_figure((640, 480), |root| {
// The following code will create a chart context
let mut chart = ChartBuilder::on(&root)
.caption("PseudoRandom Hash Point Distribution", ("Arial", 20).into_font())
.x_label_area_size(40)
.y_label_area_size(40)
.build_cartesian_2d(0f64..1f64, 0f64..1f64)?;
chart.configure_mesh()
.disable_x_mesh()
.disable_y_mesh()
.draw()?;
chart.draw_series(random_points.iter().map(|[x,y]| Circle::new((*x,*y), 3, GREEN.filled())))?;
// You can alawys freely draw on the drawing backend
let area = chart.plotting_area();
area.draw(&Cross::new((0.5, 0.5), 5, &RED))?;
Ok(())
}).style("width:60%")
:dep plotters = { version = "^0.3.0", default_features = false, features = ["evcxr", "all_series", "all_elements"] }
extern crate plotters;
use plotters::prelude::*;
evcxr_figure((640, 480), |root| {
let areas = root.split_evenly((2,1));
let mut charts = vec![];
// The following code will create a chart context
for (area, name) in areas.iter().zip(["X", "Y"].into_iter()) {
let mut chart = ChartBuilder::on(&area)
.caption(format!("Histogram for {}", name), ("Arial", 20).into_font())
.x_label_area_size(40)
.y_label_area_size(40)
.build_cartesian_2d(0u32..100u32, 0f64..0.1f64)?;
chart.configure_mesh()
.disable_x_mesh()
.disable_y_mesh()
.y_labels(5)
.x_label_formatter(&|x| format!("{:.1}", *x as f64 / 100.0))
.y_label_formatter(&|y| format!("{}%", (*y * 100.0) as u32))
.draw()?;
charts.push(chart);
}
let hist_x = Histogram::vertical(&charts[0])
.style(RED.filled())
.margin(0)
.data(random_points.iter().map(|[x,_]| ((x*100.0) as u32, 0.01)));
let hist_y = Histogram::vertical(&charts[0])
.style(GREEN.filled())
.margin(0)
.data(random_points.iter().map(|[_,y]| ((y*100.0) as u32, 0.01)));
charts[0].draw_series(hist_x)?;
charts[1].draw_series(hist_y)?;
Ok(())
}).style("width:60%")
evcxr_figure((640, 480), |root| {
let root = root.titled("Scatter with Histogram Example", ("Arial", 20).into_font())?;
let areas = root.split_by_breakpoints([560], [80]);
let mut x_hist_ctx = ChartBuilder::on(&areas[0])
.y_label_area_size(40)
.build_cartesian_2d(0u32..100u32, 0f64..0.5f64)?;
let mut y_hist_ctx = ChartBuilder::on(&areas[3])
.x_label_area_size(40)
.build_cartesian_2d(0f64..0.5f64, 0..100u32)?;
let mut scatter_ctx = ChartBuilder::on(&areas[2])
.x_label_area_size(40)
.y_label_area_size(40)
.build_cartesian_2d(0f64..1f64, 0f64..1f64)?;
scatter_ctx.configure_mesh()
.disable_x_mesh()
.disable_y_mesh()
.draw()?;
scatter_ctx.draw_series(random_points.iter().map(|[x,y]| Circle::new((*x,*y), 3, GREEN.filled())))?;
let x_hist = Histogram::vertical(&x_hist_ctx)
.style(RED.filled())
.margin(0)
.data(random_points.iter().map(|[x,_]| ((x*100.0) as u32, 0.01)));
let y_hist = Histogram::horizontal(&y_hist_ctx)
.style(GREEN.filled())
.margin(0)
.data(random_points.iter().map(|[_,y]| ((y*100.0) as u32, 0.01)));
x_hist_ctx.draw_series(x_hist)?;
y_hist_ctx.draw_series(y_hist)?;
Ok(())
}).style("width:60%")