olavolav / uniplot

Lightweight plotting to the terminal. 4x resolution via Unicode.
MIT License
343 stars 16 forks source link

Support for using datetime values for x axis labels #8

Closed ghost closed 4 months ago

ghost commented 3 years ago

Hi again @olavolav. If I am not wrong, currently there is support for only using Number Datatypes on both the x and y axes. However, while performing time series analysis and plotting trends for the time, we often need to mention the time(month/ date etc.) as a string. I am looking for something similar to this but on the terminal. image

I dont think that you need to perform any sorting for the date and such internally and we can probably mandate that the user itself sorts the list prior to plotting. Can this be supported?

olavolav commented 3 years ago

Hi @gourisariah that's a good point, indeed plotting data with time stamps and/or categorical data would be great.

I suppose a simple workaround for now would be to ask the users to map the timestamps to "number of day since X" or similar before plotting. But I agree with you that what you showed would be much nicer.

I'll think about it, and will also refresh my memory on how matplotlib and other plotting libraries handle this.

Can't promise anything right now, but I'll look into it. Thanks for the input! 😄

ghost commented 3 years ago

Sure @olavolav. That would be great! Thanks a lot.

ryanwwest commented 1 year ago

Adding my vote for this. Using datetime.datetime would helpful tons of data visualizations.

leighleighleigh commented 5 months ago

I've got a proof-of-concept implementation of this here, which I haven't PR'd due to it being tangled up with other changes. I'd appreciate your thoughts on it, @olavolav - it feels a little hacky to me, but it does work :)

olavolav commented 5 months ago

Awesome, thanks @leighleighleigh ! I will have a detailed look once I had a bit more time.

olavolav commented 5 months ago

@leighleighleigh Quick update: Inspired by your work, I have started work on this. Check out this branch if you are interested: https://github.com/olavolav/uniplot/tree/os_from_leighleighleighz-datetime_support

It is similar to your approach, but differs in a few areas to keep with uniplot's (as of yet undocumented) design goals:

  1. No additional dependencies, just Python and NumPy
  2. No required configuration, it should "just work". In building uniplot I tried to take on complexity as part of the library, such that the user could just throw data at the plot function and uniplot would figure out the rest.
  3. Nice & friendly axis labels: This is 99% missing right now, I'm just trying to find any date labels right now.

Example of what I have so far:

import numpy as np
dates =  np.arange('2002-10-27T04:30', 4*60, 60, dtype='M8[m]')
plot(xs=dates, ys=[1,2,3,2])

yields:

┌────────────────────────────────────────────────────────────┐
│                                       ▝                    │ 3
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                    ▘                                      ▝│ 2
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│                                                            │
│▖                                                           │ 1
└────────────────────────────────────────────────────────────┘
  04:52:21.900   05:37:27.300   06:22:32.700   07:07:38.100

I'll update this thread as work progresses.

olavolav commented 4 months ago

@leighleighleigh I've opened a pull request with a first working version, feel free to check it out and let me know what you think.

leighleighleigh commented 4 months ago

Just checked it out - looks great! The auto-scaling axis labels are really nice. Have confirmed our test suite still runs perfectly fine with this new version, too. uniplot has been fantastic for understanding our unit-test failures by the way, many thanks!

olavolav commented 4 months ago

Just keeping this open until the feature is complete

olavolav commented 4 months ago

And we are live as of version v0.12.1 🚀

Thanks everyone for your support and your patience 😄

olavolav commented 4 months ago

Just for the record, I wanted to see how the original request from 2021 would look like now. Taking the stock price of Meta from Yahoo as a CSV, we have:

data = pd.read_csv("META.csv")
data["Timestamp"] = pd.to_datetime(data["Date"])
plot(xs=data.Timestamp, ys=data.Close, title="Meta stock price", y_unit=" $", lines=True)

which yields

                       Meta stock price
┌────────────────────────────────────────────────────────────┐
│                                                           ▐│
│                                                           ▞│
│                                                           ▌│ 400 $
│                                              ▗▖           ▌│
│                                              ▌▌          ▐ │
│                                             ▞ ▚▞▖      ▗ ▛ │
│                                         ▗  ▐    ▌      ▞▞▘ │ 300 $
│                                         ▐▙▜▞    ▌     ▗▘   │
│                                         ▌ ▝▘    ▌     ▞    │
│                                        ▞        ▜▖    ▌    │
│                           ▖▗ ▟   ▐▟▚▐▀▙▘         ▜   ▐     │ 200 $
│                         ▗▀▝▘▛ ▀▖▐▞▘ ▘ ▝           ▙▖ ▞     │
│                     ▄▖▗▀▀      ▝▌                  ▙▗▘     │
│                 ▄▚▀▀ ▝▘                            ▐▛      │ 100 $
│          ▗▄▄▄▄▀▀                                   ▝       │
│      ▄▄▀▀▘                                                 │
│▙▄▄▄▄▞▘                                                     │
└────────────────────────────────────────────────────────────┘
  2013    2014   2016    2017   2019    2020   2021    2023

There is room for improvement, but it works for the moment, I would say.