型について本を読むのにも飽きてきたので、2日目、3日目にやってみてうまくいかなかった、DataFrameのデータに対するヒストグラム描画を再チャレンジしてみた。

まず、3日目終了時点でのコードはこんな感じ

fn draw_histogram(df: DataFrame) -> Result<DataFrame> {
	let root = BitMapBackend::new("lidar_200_histogram.png", (640, 480)).into_drawing_area();

	root.fill(&WHITE).expec("Failed to fill histogram");

	let lidar = df.column("lidar").expect("could not find `lidar` column");
	let lidar_max = lidar.max().expect("cannot take max operation") as u32;
	let lidar_min = lidar.min().expect("cannot take min operation") as u32;

	let mut chart = ChartBuilder::on(&root)
		.x_label_area_size(35)
		.y_label_area_size(40)
		.margin(5)
		.caption("Lidar Histogram", ("sans-serif", 30))
		.build_cartesian_2d((lidar_min..lidar_max).into_segmented(), 0i64..5000i64)
		.expect("could not prepare chart");

	chart
		.configure_mesh()
		.bold_line_style(&WHITE.mix(0.3))
		.y_desc("Count")
		.x_desc("Lidar")
		.axis_desc_style(("sans-serif", 15))
		.draw()
		.expect("could not draw chart");

	chart
		.draw_series(
			Histogram::vertical(&chart)
				.style(BLUE.mix(0.5).filled())
				.data(lidar.u32().into_iter().map(|x| (*x, 1))),
		)
		.expect("Could not draw serise");

	Ok(df)	
}

さて、これにコンパイルを試みると

error[E0277]: the trait bound `SegmentValue<u32>: From<ChunkedArray<UInt32Type>>` is not satisfied
  --> src/main.rs:69:18
   |
69 |                 .data(lidar.u32().into_iter().map(|x| (*x, 1))),
   |                  ^^^^ the trait `From<ChunkedArray<UInt32Type>>` is not implemented for `SegmentValue<u32>`
   |
   = help: the following implementations were found:
             <SegmentValue<T> as From<T>>
   = note: required because of the requirements on the impl of `Into<SegmentValue<u32>>` for `ChunkedArray<UInt32Type>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `lidar_200`

みたいなエラーが出てくる。これを直す方法を一つ一つ見ていく。まず、

lidar.u32()

の部分だが、これは実は失敗する。lidarの中にあるChunkedArrayChunkedArray<i64>のためだ。従ってここはlidar.i64()とするべきだが、さらに.unwrap()してやる必要がある。従って

lidar.i64().unwrap().into_iter().map(|x| (*x, 1))

となる。しかしiter()は参照を返す一方でinto_iter()は中身の値を返すらしいので

lidar.i64().unwrap().into_iter().map(|x| (x, 1))

としてやる。これでもまだダメで、xにはOptionが入るらしいので.unwrap()してやって

lidar.i64().unwrap().into_iter().map(|x| (x.unwrap(), 1))

となる。

しかしこれだけではまだ足らない。

let lidar_max = lidar.max().expect("cannot take max operation") as u32;

の部分は.expect()の手前で型が判明している必要があるため型アノテーションをしてやる必要がある。また、ここでu32にキャストしているのは後で