Logarithmic axis

Is there an easy way to change the y-axis from linear to logarithmic?

use std::io;
use plotters::prelude::*;
use std::process::Command;

fn collatz(mut n: i128) -> Vec<i128> {
    let mut sequence = vec![n];

    while n != 1 {
        if n % 2 == 0 {
            n = n / 2;
        } else {
            n = 3 * n + 1;
        }
        sequence.push(n);
    }

    sequence
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("Enter an integer for the Collatz sequence:");

    let mut input_value = String::new();
    io::stdin().read_line(&mut input_value)?;

    let input_value = match input_value.trim().parse::<i128>() {
        Ok(value) if value > 0 => value,
        _ => {
            println!("Invalid input. Please provide a valid positive integer.");
            return Ok(());
        }
    };

    let sequence = collatz(input_value);

    // Create a plot
    let root = BitMapBackend::new("collatz_sequence.png", (800, 600)).into_drawing_area();
    root.fill(&WHITE)?;

    let max_value = *sequence.iter().max().unwrap() as i128;

    let mut chart = ChartBuilder::on(&root)
        .caption("Collatz Sequence", ("sans-serif", 40))
        .x_label_area_size(50)
        .y_label_area_size(50)
        .build_cartesian_2d(0..sequence.len() as i128, 0..max_value)?;

    // Plot the Collatz sequence
    chart
        .configure_mesh()
        .x_labels(10)
        .y_labels(10)
        .draw()?;

    chart.draw_series(LineSeries::new(
        sequence.iter().enumerate().map(|(i, &val)| (i as i128, val)),
        &BLUE,
    ))?;

    // Finish the plot to ensure it's saved
    root.present()?;

    // Open the generated image using the 'open' command
    Command::new("open")
        .arg("collatz_sequence.png")
        .output()
        .expect("Failed to open image");

    Ok(())
}

From a quick glance at the documentation it seems you need to import the plotters::coord::combinators::IntoLogRange and then change the line with buile_cartesian_2d into:

.build_cartesian_2d(0..sequence.len() as i128, (0..max_value).log_scale())?;

This should make the y axis log scale.

Thank you!

That worked ou fine. However I had to replace i128 with i64 in the code because i128 seems not to be supported.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.