loony-bean / textplots-rs

Terminal plotting library for Rust
236 stars 24 forks source link

Axis ticks and plotting other data types (e.g. Dates) #9

Closed sgeisler closed 1 year ago

sgeisler commented 5 years ago

I recently discovered your library and think it's great, I'm really into CLI apps!

Since I use it for plotting a value over a longer time frame my raw data consists of (chrono::NaiveDateTime, f32) tuples. To use textplot I currently convert the chrono::NaiveDateTime to a i64 timestamp and then to a f32, which is kinda hacky. Now that still leaves me with the problem of axis ticks: they are obviously shown as float timestamps, so they are basically useless for humans.

I'm thinking about opening a PR changing the API so that Shapes accept any &[(T1, T2)] as datasource where T1: ToFloat + Display and T2: ToFloat + Display (it would need to define the ToFloat trait too).

The main drawback of that design is that it won't easily support Shape::Continuous.

Another approach would be to supply two functions that can build axis tick labels from float values. I don't really like that one since it doesn't allow for strong typing throughout the program like the first one does (bare integers/floats can be considered a code smell to some degree since they don't carry any semantics, nobody knows if it meters or euros etc.).

Do you have any thoughts/preferences regarding this feature?

loony-bean commented 5 years ago

Hey @sgeisler! Yeah, looking at dates as timestamps should feel weird :) If you think you can implement this feature, I would be happy to merge it.

Basically my core preferences are the following:

Back to your question, I'd prefer adding new types than new API function.

G0rocks commented 3 years ago

Another idea that would work for units like meters, currency and other purely numerical units (no “/“ or “-“ or “september” or anything like that) is to just add a char array to the end of the axis specifying the unit. Would of course not work for dates or time stamps but another way to display those is with the units seconds, minutes, hours, days, weeks, months, years so it shouldn’t be too much of a problem I suppose.

implementation idea: Add the char arrays as xlabel and ylabel to the chart struct and default them as empty arrays and always display the char arrays in the display function.

justinbarclay commented 3 years ago

Hey,

I've done some work on a fork of textplots-rs, called pointplots-rs the primary benefit of my fork is that it now has a built in means to print labels. It does this by changing the primary datatype from an f32 to a struct Point<T,U> where T and U implement Display, Into, From, Clone. We use this to allow us to build graphs on arbitrary data types as long as they can describe how they want to be displayed and can be converted to and from an f64 (so we know how to place them on a graph).

@loony-bean I want to start off by saying thank you for creating this library, it was so simple and straight forward to implement and modify. I really appreciate what you've done. If you are interested in my work and merging it into your project I'd be more than happy to help work with you. However, because it does change your API quite substantially I also understand why you would not want that. If you do not want to merge our work, I will probably work on getting this up on crates.io however 😅.

As an aside, I admit there are some caveats to switching to a struct based system and primarily that is because I have not found a clean way to make a Point and Shape::Continuous play nicely.

loony-bean commented 1 year ago

Hello everyone 👋 ! Label formatting has landed if you want to try it out.