loony-bean / textplots-rs

Terminal plotting library for Rust
240 stars 24 forks source link

1 fewer bars in bar chart than expected #43

Open jfharden opened 1 year ago

jfharden commented 1 year ago

Love the crate! Thanks for your efforts.

If I have 6 points to represent as bars only 5 bars are drawn.

use textplots::{Chart, Plot, Shape};

fn main() {
    let points: Vec<(f32, f32)> = vec![
        (1.0, 3.7),
        (2.0, 2.1),
        (3.0, 4.8),
        (4.0, 8.2),
        (5.0, 1.1),
        (6.0, 9.4),
    ];

    Chart::new_with_y_range(240, 120, 1.0, 6.0, 0.0, 10.0)
        .lineplot(&Shape::Bars(&points))
        .nice();
}

If I execute this I get only 5 bars (Excuse the image, I tried to paste as text but between my terminal and github it's not aligning correctly):

Screenshot 2023-04-25 at 22 28 55

But I would expect to see 6 bars in a similar way to Google Sheets/Excel:

Screenshot 2023-04-25 at 22 26 09
TDHolmes commented 1 year ago

does using an x range of 0 to 6 work?

PraxTube commented 1 year ago

You actually get the first "bar", however it doesn't render as a bar. Instead it's only one single vertical line

image

This is more clear when we start the x range from 0.0

image

As far as I can tell, this is actually how it is supposed to be. The reason is that the program starts to draw the plot from the first x value, so in this case 1.0. You can actually size the bars in any why you like, you could have them all in different shapes essentially. If you want to render the first value, I would suggest to simply do something like

let points: Vec<(f32, f32)> = vec![
    (0.0, 3.7),
    (1.0, 3.7),
    (2.0, 2.1),
    (3.0, 4.8),
    (4.0, 8.2),
    (5.0, 1.1),
    (6.0, 9.4),
];

It would be possible to create a new struct like RegularBars or something that will have uniform sizes of bars and only takes in one single Vec<f32>. Though I don't see much of a reason in that, because you can create that on your own fairly easily.

Though it is pretty non intuitive I have to agree.

ahcm commented 1 year ago

If that is the intention, I would argue to change the intention.

PraxTube commented 1 year ago

The problem is that you would have to restrict it to always have the same size (on the x axis) of bars. It would work in this case where the bars all have the same size but that is not the general case. Here is the implementation of the code. The program doesn't know where the first x value should start. In order to make that work you would have to restrict it to always use fixed sizes on the x axis.

Though I agree that you would not want a bars chart to work like this. I think the current bar should be something like GeneralBar and then we have the fixed x size bars be the Bar.

PraxTube commented 1 year ago

As for what the use case here is, you can have this for instace

image

Now how practically useful is this? No clue, I wouldn't know where you want this. But you can do that, and you can't do that with fixed x size (so it's very similar to steps, which might make this redundant all together).

loony-bean commented 1 year ago

Hi guys! I understand that it is confusing, but using Bars will not create bar plot. This is still a line plot but with somewhat more fancy display. Bar plots are quite different, for instance one axis of it could be qualitative, and we could render it horizontally (like here).