kroitor / asciichart

Nice-looking lightweight console ASCII line charts ╭┈╯ for NodeJS, browsers and terminal, no dependencies
MIT License
1.84k stars 94 forks source link

Failure with very long series #41

Closed ivanprado closed 4 years ago

ivanprado commented 4 years ago

Since version 1.5.10 the following fails:

asciiplot([1.]*1000, 80, 15)

With the following error:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
kroitor commented 4 years ago

@ivanprado can you show your asciiplot definition plz?

ivanprado commented 4 years ago

@kroitor what do you mean with asciiplot definition?

I forget to say that this is failing in the python version.

kroitor commented 4 years ago

@ivanprado i mean, it does not have an asciiiplot function that would accept 3 arguments as in your snippet. But, anyways, i think i'll upload a fix shortly. Thx!

ivanprado commented 4 years ago

Ohh, you are right! Sorry I miss that. This is the function I'm using:

def asciiplot(y, width: int, height: int):
    """Return a string with a plot of the array as a nice ascii chart"""
    n = len(y)
    slice_size = n // width + bool(n % width)
    if n > width:
        y = np.pad(y, (0, slice_size * width - n), 'edge')
        y = y.reshape((-1, slice_size)).mean(axis=1)
    return asciichartpy.plot(y, {"height": height})

I'm converting the array to numpy, and this could be causing the problem in asciichartpy.

kroitor commented 4 years ago

@ivanprado thank you so much! Uploaded a fix to it, let me know if you have issues with version 1.15.12. Appreciate your help!

ivanprado commented 4 years ago

@kroitor thank you for having time to look into that. I've tried version 1.15.12 and keeps failing for my case. This is the way you can reproduce it:

import numpy as np
from asciichartpy import plot
plot(np.arange(10))

The problem is only for numpy arrays, because the following is working:

import numpy as np
from asciichartpy import plot
plot(np.arange(10).tolist())

It was not failing with previous versions. Maybe is just that asciiplot doesn't support numpy arrays anymore, that's also fine, not a mayor problem.

kroitor commented 4 years ago

@ivanprado can you plz elaborate with more details (error callstack, output)?

I've tried your snippet (you have to print the result of plot) and it works on my side with 1.5.12:

mbp:asciichart igorkroitor$ python3
Python 3.7.2 (v3.7.2:9a3ffc0492, Dec 24 2018, 02:44:43)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> from asciichartpy import plot
>>> print(plot(np.arange(10).tolist()))
    9.00  ┼        ╭
    8.00  ┤       ╭╯
    7.00  ┤      ╭╯
    6.00  ┤     ╭╯
    5.00  ┤    ╭╯
    4.00  ┤   ╭╯
    3.00  ┤  ╭╯
    2.00  ┤ ╭╯
    1.00  ┤╭╯
    0.00  ┼╯
>>>

Do you have a different result with the same lines ↑ ?

and keeps failing for my case

When you say that it's failing – can you, plz, describe how exactly it is failing by copypasting the output? Need the details, really. Thx for your involvement!

ivanprado commented 4 years ago

You have to remove the .tolist():

➜ python3
Python 3.6.6 (default, Sep 12 2018, 18:26:19) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> from asciichartpy import plot
>>> plot(np.arange(10))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ivan/Documentos/scrapinghub/dev/web-rcnn-venv/lib/python3.6/site-packages/asciichartpy/__init__.py", line 80, in plot
    if not series or all(isnan(n) for n in series):
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> 
kroitor commented 4 years ago

@ivanprado ok, i've uploaded one more fix to it, please let me know if it works for you with 1.15.13:

mbp:asciichart igorkroitor$ python3
Python 3.7.2 (v3.7.2:9a3ffc0492, Dec 24 2018, 02:44:43)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import asciichartpy
>>> import numpy
>>> print(asciichartpy.plot(numpy.arange(10)))
    9.00  ┼        ╭
    8.00  ┤       ╭╯
    7.00  ┤      ╭╯
    6.00  ┤     ╭╯
    5.00  ┤    ╭╯
    4.00  ┤   ╭╯
    3.00  ┤  ╭╯
    2.00  ┤ ╭╯
    1.00  ┤╭╯
    0.00  ┼╯

Looking forward to hearing back from you.

ivanprado commented 4 years ago

It works perfectly! Thank you @kroitor

kroitor commented 4 years ago

@ivanprado thx, appreciate your feedback!

pkazmier commented 4 years ago

This fix has broken asciichartpy for me. Plotting a series of 0 values will now return an empty string instead of a graph with 0 values plotted:

>>> plot([0,0,0,0])
''

By using any, a regular python list of 0 values will evaluate as False.

The simple fix here is to change:

if not any(series) or all(isnan(n) for n in series):

to explicitly check for the length of the series:

if len(series) == 0 or all(isnan(n) for n in series):
pkazmier commented 4 years ago

Works again, thanks for the instant turnaround!