型について本を読むのにも飽きてきたので、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の中にあるChunkedArray
がChunkedArray<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にキャストしているのは後で