昨日は、ヒストグラムを出力するところまでで終わってしまった。いつまでヒストグラムやってるんだって感じなので早く先に行きたい
ヒストグラムを描くサンプルコードは次のような感じだった
use plotters::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let root = BitMapBackend::new("histogram.png", (640, 480)).into_drawing_area();
root.fill(&WHITE)?;
let mut chart = ChartBuilder::on(&root)
.x_label_area_size(35)
.y_label_area_size(40)
.margin(5)
.caption("Histogram Test", ("sans-serif", 50))
.build_cartesian_2d((0u32..10u32).into_segmented(), 0u32..10u32)?;
chart
.configure_mesh()
.disable_x_mesh()
.bold_line_style(&WHITE.mix(0.3))
.y_desc("Count")
.x_desc("Bucked")
.axis_desc_style(("sans-serif", 15))
.draw()?;
let data = [
0u32, 1, 1, 1, 4, 2, 5, 7, 8, 6, 4, 2, 1, 8, 3, 3, 3, 4, 4, 3, 3, 3,
];
chart.draw_series(
Histogram::vertical(&chart)
.style(RED.mix(0.5).filled())
.data(data.iter().map(|x: &u32| (*x, 1))),
)?;
Ok(())
}
これをDataFrameを受け取るようにし、その中で"lidar"というカラムに対して描画をするように変えたい、というのが今回考えていることだ。まず次のような感じにしてみた。変更点は、build_cartesian_2d
の中で横軸をデータに合わせて範囲指定するようにしたことと、データをDataFrameに格納されているものを使うようにしたことぐらいだ。
fn draw_histogram(df: DataFrame) -> Result<(), Box<dyn std::error::Error>> {
let root = BitMapBackend::new("lidar_200_histogram.png", (640, 480)).into_drawing_area();
root.fill(&WHITE)?;
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(), 0u32..5000u32)?;
chart
.configure_mesh()
.bold_line_style(&WHITE.mix(0.3))
.y_desc("Count")
.x_desc("Lidar")
.axis_desc_style(("sans-serif", 15))
.draw()?;
chart
.draw_series(
Histogram::vertical(&chart)
.style(BLUE.mix(0.5).filled())
.data(lidar.into_iter().map(|x: &i64| (*x, 1))),
)?;
Ok(df)
}
しかしこれでは次のようなエラーが出てしまう
--> src/main.rs:39:48
|
39 | fn draw_histogram(df: DataFrame) -> Result<(), Box<dyn std::error::Error>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ unexpected type argument
error: aborting due to previous error
For more information about this error, try `rustc --explain E0107`.
error: could not compile `lidar_200`
そもそもResult
とは?Box
とは?dyn
とは?という感じなのでどう直せばいいかわからない。とりあえず調べてみよう。以下、E0107の内容だが・・・うん、意味わからん
Result
に与えられるパラメータ?が多すぎるという意味だろうか?しかしこれは前のヒストグラムのサンプルコードの時はバッチリ動いていたんだが・・・。
とりあえずResult
が怪しいので調べてみた。
The Rust Programming Language 日本語版
うーむ、わからん・・・どうやら、関数内で?
を使うとその式の結果がエラーになった場合はそこで終了してエラーを返してくれる、そうでなければその式を評価した結果が返される、というようになっているらしい。確かに関数内では何箇所か?
使っている。しかし、これがどうunexpected type argumentに繋がるのかかけらもわからん。
よくわからないので、とりあえず?
をやめて全部.expect()
に変えた上で関数の返り値をResult<DataFrame>
に変えてみたらよくわからないエラーは全部消えて