Git Product home page Git Product logo

uniplot's Issues

plot fails when multiseries is provided with empty list

In my use-case the list of numbers are dynamically generated, which sometimes create something like this:

plot([[1,2,3,4,3,2,3,4],[3,2,2,4,1,2,1,4],[1,3],[]], lines=True)

Which fails, i think during validation, extracting the max. It also happens with x,y data (which is actually my case).

Looking at the logic I think probably is wise to exclude them from the multi series, but that may also interact with the colors, other possible solution is changing some functions like:

def y_max(self) -> float:
    return max([_safe_max(ys_row) for ys_row in self.ys])

#to

def y_max(self) -> float:
    return max([_safe_max(ys_row) for ys_row in self.ys if len(self.ys) >0])

Fill area under curve

This was on the roadmap but have not heard anyone actually request it. So I'll leave the prototypical hack here as an issue in case anyone wants to actually have it.

So in theory we could have an option like y_fill_level that enables filling the are between the points and a given vertical level, usually the zero line.

It might look something like:

plot(ys, title="Sine wave", y_fill_level=-2.5)
                          Sine wave
┌────────────────────────────────────────────────────────────┐
│                                                    ▟█▙     │ 
│                                                   ▗███▌    │ 
│                                       ▗██▖        ▟████    │ 
│                                       ▟███       ▗█████▌   │ 2
│                           ▟█▙        ▗████▌      ▐██████   │ 
│                          ▐███▖       ▟█████      ███████▌  │ 
│              ▗██▖        █████      ▗██████▌    ▐████████  │ 
│              ███▙       ▗█████▖     ▐██████▙    ▟████████▌ │ 
│  ▟█▖        ▐████▖      ▟█████▙     ████████▖  ▗██████████▄│ 1
│ ▐███▖       █████▙      ███████▖   ▗████████▙  ▟███████████│ 
│ ████▙      ▗██████▖    ▐███████▙   ▟█████████▙▟████████████│ 
│▐█████▖     ▐██████▌    █████████▖ ▗████████████████████████│ 
│▟█████▌     ████████   ▗██████████▄█████████████████████████│ 
│███████────▐████████▙──▟████████████████████████████████████│ 0
│███████▌   ██████████▙▟█████████████████████████████████████│ 
│████████  ▐█████████████████████████████████████████████████│ 
│████████▙▄██████████████████████████████████████████████████│ 
└────────────────────────────────────────────────────────────┘
         100       200       300       400       500       600

And then with colors it might look like:
Screen Shot 2021-05-01 at 18 18 25

Let me know if this feature would be useful.

Get a plot as a string

I'm working on a tool that I would love to be able to integrate uniplot into, but I'm running into a problem: I need to capture the output as a string so that I can display it elsewhere. Right now, uniplot.plot prints directly to stdout: https://github.com/olavolav/uniplot/blob/master/uniplot/uniplot.py#L74

I'm not sure how to square this with the interactive features implemented in that function. Perhaps a helper function could be extracted that returns the plot as a string? Then I could call that function from my tool to get the string that uniplot.plot would have displayed.

Happy to do the work on this if you can provide some guidance on how you'd like it implemented!

Incorrect axis labels in rare cases

See here, the correct labels are computed in terms of floating point numbers [-1.4 -0.9 -0.4] but then the string labels are "-0.4", "-0.9" and "-1". The last one is wrong, should of course be "-1.4" so it is cut off at the wrong digit.

See this example:

>>> from uniplot.axis_labels.extended_talbot_labels import extended_talbot_labels
>>> extended_talbot_labels(x_min=-1.846526999372103, x_max=-0.1651564799721942, available_space=17, vertical_direction=True, verbose=True).render()
DEBUG: x_min = -1.846526999372103
DEBUG: x_max = -0.1651564799721942
DEBUG: simplicity = 0.19999999999999996, coverage = 0.9940240106065467, density = -4.666666666666667, grid_alignment = 1 => New best score 😀 = -0.9014939973483634 with labels = [-1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1 -1.  -0.9 -0.8 -0.7 -0.6 -0.5
 -0.4 -0.3 -0.2]
DEBUG: simplicity = 0.0, coverage = 0.549810354275108, density = 0.0, grid_alignment = 1 => New best score 😀 = 0.337452588568777 with labels = [-1.4 -0.9 -0.4]
['', '', '-0.4', '', '', '', '', '-0.9', '', '', '', '', '-1', '', '', '', '']

Configurable move / zoom keys

After using uniplot now for a couple days, I found myself using the interactive mode quite often for some simple EDA on remote resources. However, I've been struggling a bit with the h/j/k/l key combinations for moving the bounding box ("struggling" is perhaps a too strong word here ^^), so I've been wondering if you would be up for having this configurable. If this option existed, I would change it to w/a/s/d.

The Options dataclass could be a good place for that, however, the question is whether this should be configurable per plot/histogram() call (1), or a global setting (2).

I don't believe people would need to change this behavior from plot to plot, so option 2 could make more sense here. In this case, a ClassVar on Options would already do the trick, allowing for (e.g.)

import uniplot
uniplot.Options.move_keys = "wasd"
uniplot.plot(...)

(just as an example, a proper setter is of course preferable here to change the class var)

Occasional gaps in lines

Sometimes there are gaps at the end of lines.

To reproduce

>>> from uniplot import plot
>>> plot(xs=[0.433,0.6666], ys=[0.8,0.1133], x_min=0, x_max=1, y_min=0, y_max=1, lines=True)
DEBUG indices_slope -0.8571428571428571 slope -2.939640410958905
DEBUG x_index_start 51
DEBUG x_index_stop 79
DEBUG x_indices_of_line [52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
 76 77 78]
┌────────────────────────────────────────────────────────────┐
││                                                           │ 1.0
││                                                           │ 
││                                                           │ 
││                        ▝▖                                 │ 
││                         ▝▚                                │ 0.7
││                           ▚                               │ 
││                            ▚▖                             │ 
││                             ▝▖                            │ 
││                              ▝▖                           │ 0.5
││                               ▝▚                          │ 
││                                 ▚                         │ 
││                                  ▚▖                       │ 
││                                   ▝▖                      │ 0.3
││                                    ▝▖                     │ 
││                                     ▝▘                    │ 
││                                      ▝                    │ 
││▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁│ 0.0
└────────────────────────────────────────────────────────────┘
 0                                                          1

This is not a bug, but an artifact of the line drawing attempting to be accurate. If the end pixel is drawn because of an end pint that is significantly away from the center of the pixel then this is possible.

Possible solutions

  • The obvious solution would be to draw the line between the middle points of the start and end pixel, not the actual line.
  • An alternative might be to check for gaps and correct it by drawing another pixel.

Suggestion for speeding up large data

Nice project!

So basically I have noticed that plotting has linear speed,

range(10_000_000) took 10x as long to plot as range(1_000_000)


If you are aware of the max resolution, then you could imagine you can compress the data, without resulting in a different plot

One way (probably it's possible to come up with something much better), would be to perhaps fit 1000 linear regressions on sorted data of 10_000_000 data points and use that to e.g. compress 10_000_000 rows into 1_000_000 (or less) - whatever is needed for the solution, basically the sign could be "0=stay equal, -decrease, +increase"

I was able to fit 1000 regressions in 300ms, whereas the naive plotting went from 1s to 10s, so a huge speed-up would be possible if you are able to compress the data

Label choice does not always seem optimal

In the example of #15 actually it is curious that the .5 labels are not chosen by the algorithm.

>>> from uniplot.axis_labels.extended_talbot_labels import extended_talbot_labels
>>> extended_talbot_labels(x_min=-1.846526999372103, x_max=-0.1651564799721942, available_space=17, vertical_direction=True, verbose=True).render()
### exponent = 0 ###
(...)
### exponent = -1 ###
### j = 1 ###
### i = 0, q = 1 ###
Testing labels: [-1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1 -1.  -0.9 -0.8 -0.7 -0.6 -0.5
 -0.4 -0.3 -0.2] => simplicity = 0.19999999999999996, coverage = 0.9940240106065467, density = -4.666666666666667, grid_alignment unknown => score_approx = -0.8514939973483636
Testing labels: [-1.8 -1.7 -1.6 -1.5 -1.4 -1.3 -1.2 -1.1 -1.  -0.9 -0.8 -0.7 -0.6 -0.5
 -0.4 -0.3 -0.2] => simplicity = 0.19999999999999996, coverage = 0.9940240106065467, density = -4.666666666666667, grid_alignment => 1, score = -0.8514939973483636
=> New best score 😀
### i = 1, q = 5 ###
Testing labels: [-1.4 -0.9 -0.4] => simplicity = 0.0, coverage = 0.549810354275108, density = 0.0, grid_alignment unknown => score_approx = 0.337452588568777
Testing labels: [-1.4 -0.9 -0.4] => simplicity = 0.0, coverage = 0.549810354275108, density = 0.0, grid_alignment => 1, score = 0.337452588568777
=> New best score 😀
(...)
### j = 5 ###
### i = 0, q = 1 ###
Testing labels: [-1.4 -0.9 -0.4] => simplicity = -3.8, coverage = 0.549810354275108, density = 0.0, grid_alignment unknown => score_approx = -1.5625474114312228
Testing labels: [-1.8 -1.3 -0.8 -0.3] => simplicity = -3.8, coverage = 0.9640122259435896, density = -0.33333333333333326, grid_alignment unknown => score_approx = -1.5589969435141025
Testing labels: [-1.7 -1.2 -0.7 -0.2] => simplicity = -3.8, coverage = 0.9598794169078467, density = -0.33333333333333326, grid_alignment unknown => score_approx = -1.5600301457730383
Testing labels: [-1.6 -1.1 -0.6] => simplicity = -3.8, coverage = 0.5580759723465938, density = 0.0, grid_alignment unknown => score_approx = -1.5604810069133515
Testing labels: [-1.5 -1.  -0.5] => simplicity = -3.8, coverage = 0.5893162650552402, density = 0.0, grid_alignment unknown => score_approx = -1.55267093373619

It seems odd that the simplicity for the intuitive choice of [-1.5, -1.0, -0.5] is negative.

Let's investigate, could be a bug.

Histogram x-axis range ignored

Hi again,

after playing around a bit more with histograms, I noticed that the x-axis range is ignored in cases where the number of bins as well as min/max values are provided (histogram(data, bins=..., x_min=..., x_max=...)).

Here is a reproducer:

import numpy as np
from uniplot import histogram

data = np.random.uniform(0, 3, size=1000)
histogram(data, bins=4, x_min=-0.5, x_max=3.5)

# ->
┌────────────────────────────────────────────────────────────┐
│       ▐▀▀▀▀▀▀▀▀▀▀▜          ▐▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▌       │
│       ▐          ▐          ▐                      ▌       │
│       ▐          ▝▀▀▀▀▀▀▀▀▀▀▀                      ▌       │
│       ▐                                            ▌       │ 200
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│       ▐                                            ▌       │ 100
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│       ▐                                            ▌       │
│▁▁▁▁▁▁▁▐▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▌▁▁▁▁▁▁▁│ 0
└────────────────────────────────────────────────────────────┘
        0              1              2              3

The axis range is of course correct, but I would have expected that the left edge of the first bin and the right edge of the last bin landed on -0.5 and 3.5, respectively.

I could provide a PR, but I first wanted to check if the current behavior was intended.

Support for using datetime values for x axis labels

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?

Missing precision on x axis values, making them identical

Hello Olav,
I have noticed a small problem when displaying the x axis values. The values seem to be rounded too much making them identical and equal to 0. It seems to happen when one value is positive, the other negative and the values are close to 0 (+-0.01) I included screenshots of it.

PS: uniplot feels great, keep it up!

Screenshot 2021-01-22 at 16 58 48

Screenshot 2021-01-22 at 17 08 59

Missing link to repository on PyPI page

I'm not familiar with poetry, but in standard python projects this would be fixed by setting the following in pyproject.toml:

[project.urls]
repository = "https://github.com/olavolav/uniplot"
documentation = <docs website, if any>

Just a small gripe

Extra lines are drawn that shouldn't be there

To Reproduce:

>>> plot(xs=[1,1], ys=[0,1], lines=True, x_min=3, x_max=6)
┌────────────────────────────────────────────────────────────┐
│                    ▖                                       │ 1.0
│                    ▌                                       │ 
│                    ▌                                       │ 
│                    ▌                                       │ 
│                    ▌                                       │ 0.7
│                    ▌                                       │ 
│                    ▌                                       │ 
│                    ▌                                       │ 
│                    ▌                                       │ 0.5
│                    ▌                                       │ 
│                    ▌                                       │ 
│                    ▌                                       │ 
│                    ▌                                       │ 0.3
│                    ▌                                       │ 
│                    ▌                                       │ 
│                    ▌                                       │ 
│▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▌▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁│ 0.0
└────────────────────────────────────────────────────────────┘
 3                                                          6

Obviously there should not be anything drawn in this view.

Here, the correct line is drawn, but also weird other ones. In interactive mode this line appears once the real one is out of view.

[Question] Does Uniplot Support .py files?

Hello,

This is an interesting project! Thank you for taking the time to put it together.

Quick question:

When testing out uniplot I'm able to call .plot() from the python console or through ipython, and get a visualization quite easily. However, it does not work when I include uniplot in a .py file and I execute the file.

# foo.py
import unipolot as plot
import math
x = [math.sin(i / 20) + i / 300 for i in range(600)]
p = plot(x)


$ python foo.py
Traceback (most recent call last):
  File "foo.py", line 4, in <module>
    p = plot(x)
TypeError: 'module' object is not callable

Is this expected behaviour, or am I missing something from the docs?

Thanks,

Feature request: Boxplot

I'd like to plot boxplots on the terminal along with support for multiple boxplots alongside other boxplots

Incorrect centering of labels with units

See this example:

>>> plot([1,3,2], height=2)
┌────────────────────────────────────────────────────────────┐
│                              ▘                            ▗│ 3
│▖                                                           │ 1
└────────────────────────────────────────────────────────────┘
 1                             2                            3
>>> plot([1,3,2], height=2, x_unit=" microns")
┌────────────────────────────────────────────────────────────┐
│                              ▘                            ▗│ 3
│▖                                                           │ 1
└────────────────────────────────────────────────────────────┘
 1 microns                     2 microns                    3 microns

What should happen is that the labels are centered, including the units.

Crash after zooming

To reproduce:

from uniplot import plot, histogram
import numpy as np  # type: ignore

# Exception when zooming in

xs = np.array(
    [
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29,
        30,
        31,
        32,
        33,
        34,
        35,
        36,
        37,
        38,
        39,
        40,
        41,
        42,
        43,
        44,
        45,
        46,
        47,
        48,
        49,
        50,
        51,
        52,
        53,
        54,
        55,
        56,
        57,
        58,
        59,
        60,
        61,
        62,
        63,
        64,
        65,
        66,
        67,
        68,
        69,
        70,
        71,
        72,
        73,
        74,
        75,
        76,
        77,
        78,
        79,
        80,
        81,
        82,
        83,
        84,
        85,
        86,
        87,
        88,
        89,
        90,
        91,
        92,
        93,
        94,
        95,
        96,
        97,
        98,
        99,
        100,
        101,
        102,
        103,
        104,
        105,
        106,
        107,
        108,
        109,
        110,
        111,
        112,
        113,
        114,
        115,
        116,
        117,
        118,
        119,
        120,
        121,
        122,
        123,
        124,
        125,
        126,
        127,
        128,
        129,
        130,
        131,
        132,
        133,
        134,
        135,
        136,
        137,
        138,
        139,
        140,
        141,
        142,
        143,
        144,
        145,
        146,
        147,
        148,
        149,
        150,
        151,
        152,
        153,
        154,
        155,
        156,
        157,
        158,
        159,
        160,
        161,
        162,
        163,
        164,
        165,
        166,
        167,
        168,
        169,
        170,
        171,
        172,
        173,
        174,
        175,
        176,
        177,
        178,
        179,
        180,
        181,
        182,
        183,
        184,
        185,
        186,
        187,
        188,
        189,
        190,
        191,
        192,
        193,
        194,
        195,
        196,
        197,
        198,
        199,
        200,
        201,
        202,
        203,
        204,
        205,
        206,
        207,
        208,
        209,
        210,
        211,
        212,
        213,
        214,
        215,
        216,
        217,
        218,
        219,
        220,
        221,
        222,
        223,
        224,
        225,
        226,
        227,
        228,
        229,
        230,
        231,
        232,
        233,
        234,
        235,
        236,
        237,
        238,
        239,
        240,
        241,
        242,
        243,
        244,
        245,
        246,
        247,
        248,
        249,
        250,
        251,
        252,
        253,
        254,
        255,
        256,
        257,
        258,
        259,
        260,
        261,
        262,
        263,
        264,
        265,
        266,
        267,
        268,
        269,
        270,
        271,
        272,
        273,
        274,
        275,
        276,
        277,
        278,
        279,
        280,
        281,
        282,
        283,
        284,
        285,
        286,
        287,
        288,
        289,
        290,
        291,
        292,
        293,
        294,
        295,
        296,
        297,
        298,
        299,
        300,
        301,
        302,
        303,
        304,
        305,
        306,
        307,
        308,
        309,
        310,
        311,
        312,
        313,
        314,
        315,
        316,
        317,
        318,
        319,
        320,
        321,
        322,
        323,
        324,
        325,
        326,
        327,
        328,
        329,
        330,
        331,
        332,
        333,
        334,
        335,
        336,
        337,
        338,
        339,
        340,
        341,
        342,
        343,
        344,
        345,
        346,
        347,
        348,
        349,
        350,
        351,
        352,
        353,
        354,
        355,
        356,
        357,
        358,
        359,
        360,
        361,
        362,
        363,
        364,
        365,
        366,
        367,
        368,
        369,
        370,
        371,
        372,
        373,
        374,
        375,
        376,
        377,
        378,
        379,
        380,
        381,
        382,
        383,
        384,
        385,
        386,
        387,
        388,
        389,
        390,
        391,
        392,
        393,
        394,
        395,
        396,
        397,
        398,
        399,
        400,
        401,
        402,
        403,
        404,
        405,
        406,
        407,
        408,
        409,
        410,
        411,
        412,
        413,
        414,
        415,
        416,
        417,
        418,
        419,
        420,
        421,
        422,
        423,
        424,
        425,
        426,
        427,
        428,
        429,
        430,
        431,
        432,
        433,
        434,
        435,
        436,
        437,
        438,
        439,
        440,
        441,
        442,
        443,
        444,
        445,
        446,
        447,
        448,
        449,
        450,
        451,
        452,
        453,
        454,
        455,
        456,
        457,
        458,
        459,
        460,
        461,
        462,
        463,
        464,
        465,
        466,
        467,
        468,
        469,
        470,
        471,
        472,
        473,
        474,
        475,
        476,
        477,
        478,
        479,
        480,
        481,
        482,
        483,
        484,
        485,
        486,
        487,
        488,
        489,
        490,
        491,
        492,
        493,
        494,
        495,
        496,
        497,
        498,
        499,
    ]
)
ys = np.array(
    [
        1.26230459e00,
        3.59321301e-01,
        2.11936647e00,
        1.84432132e00,
        2.27899071e00,
        1.51661172e00,
        1.95712695e-01,
        1.64582244e00,
        1.19080132e00,
        1.77906596e00,
        2.60834568e00,
        4.01352512e00,
        1.12257450e00,
        -2.38223520e-01,
        3.17199023e-01,
        2.85413316e-01,
        9.91733067e-01,
        1.84263384e00,
        2.32001561e00,
        1.33347914e00,
        3.46571661e-01,
        1.34794460e00,
        1.36144011e00,
        2.22913711e00,
        2.95592602e00,
        3.01213057e00,
        1.87905661e00,
        4.10827814e-01,
        -2.75564854e-01,
        1.03768731e00,
        -3.97770275e-01,
        3.06930582e00,
        2.78850709e00,
        1.48173807e00,
        -4.55744704e-03,
        -1.32975609e00,
        6.36077517e-02,
        1.83738438e00,
        1.68082395e00,
        1.39683868e00,
        -9.97108469e-02,
        -9.49959243e-01,
        7.88987944e-01,
        5.23096813e-01,
        1.79377985e00,
        2.56523643e00,
        1.65300403e00,
        1.40698126e00,
        7.48265081e-01,
        6.23696401e-01,
        9.13088969e-01,
        7.17841682e-01,
        1.76776214e00,
        3.85539288e00,
        1.44986447e00,
        2.91732462e-02,
        1.34081560e00,
        6.29367473e-01,
        1.89256668e00,
        -5.01236350e-01,
        2.44245545e00,
        -3.76219798e-01,
        -1.52341955e00,
        6.89569262e-02,
        3.47522530e-01,
        -1.68230067e-01,
        1.34471069e00,
        1.18431856e00,
        1.31349600e00,
        7.29997833e-01,
        2.89225012e-01,
        -2.80413712e00,
        7.50533432e-01,
        8.71114431e-01,
        7.07190831e-01,
        3.17740131e00,
        5.86036160e-01,
        5.90711279e-01,
        -7.22011344e-01,
        -1.50789690e-01,
        1.50888043e00,
        3.91049296e-01,
        2.35969482e00,
        1.08970815e00,
        1.42594895e00,
        4.96137247e-01,
        1.30358513e00,
        3.34551072e00,
        1.93665667e00,
        1.53050683e00,
        2.36212454e00,
        -5.24698604e-01,
        4.42035630e-02,
        -9.42400877e-01,
        9.51652062e-01,
        -6.94684749e-01,
        2.91913781e00,
        4.31538812e-02,
        -1.24747396e00,
        7.96053706e-02,
        1.87125758e00,
        3.24216046e00,
        1.21241355e00,
        1.18453587e00,
        -6.06840947e-01,
        -5.66081726e-01,
        1.95866564e00,
        1.73761292e-01,
        1.45443360e00,
        3.12741942e00,
        2.18546158e00,
        3.38033204e-01,
        7.39796805e-02,
        -4.12367686e-01,
        2.09752078e00,
        2.94173384e00,
        1.43576006e00,
        2.35233888e00,
        1.75026987e-01,
        -7.96761454e-01,
        1.16392155e00,
        3.95625636e-01,
        3.25318881e00,
        1.50728811e00,
        4.19976468e00,
        2.68370507e-01,
        2.61967644e00,
        -8.89491321e-02,
        2.55987916e00,
        2.56399322e00,
        9.51770979e-01,
        6.74653511e-01,
        2.33729281e-01,
        -7.14686280e-01,
        -2.67159716e-01,
        1.13894794e00,
        3.23252390e00,
        1.33774678e00,
        1.31868005e00,
        1.81951904e-01,
        4.79242635e-01,
        2.15532864e-01,
        6.92885478e-01,
        1.70927123e00,
        1.32722492e00,
        1.44586826e00,
        1.29820650e00,
        3.99065294e-01,
        -5.78380524e-01,
        9.27519202e-01,
        2.47403927e-01,
        1.55674871e00,
        -3.25379422e-01,
        1.09442721e00,
        -4.74897587e-01,
        1.93365775e00,
        1.41704079e00,
        2.91712317e00,
        2.66207768e00,
        1.84139843e-01,
        1.37767813e-01,
        1.25142357e00,
        4.84057548e-01,
        6.07245680e-01,
        3.30181350e-01,
        2.43432229e00,
        2.56402791e00,
        -6.93171018e-01,
        6.68779033e-01,
        -1.94396361e-01,
        1.51260020e00,
        2.49096620e00,
        2.45031139e00,
        3.03096170e-01,
        -8.18876084e-01,
        8.19588735e-01,
        -1.17728460e00,
        -1.16854500e00,
        2.44811633e00,
        1.93316841e00,
        1.37030049e00,
        7.81292142e-01,
        4.01495947e-01,
        1.47579864e-01,
        -2.84856788e-01,
        1.98363074e00,
        2.19940360e00,
        -8.05836667e-01,
        1.46269262e00,
        -7.71479430e-01,
        -4.29736882e-01,
        1.49405237e00,
        1.83036686e00,
        9.27646287e-01,
        1.42684947e00,
        -1.47479979e00,
        -2.83542544e00,
        -1.32329789e00,
        8.63657805e-01,
        1.67849080e00,
        2.90746670e-01,
        1.21004861e00,
        -1.20775413e00,
        -5.31279246e-01,
        1.56967687e00,
        1.83278302e00,
        9.72991848e-01,
        1.67934543e00,
        1.94689352e00,
        -1.29059489e00,
        -1.66424333e-01,
        6.79751734e-01,
        1.91516968e00,
        1.71575116e00,
        1.79466158e00,
        5.07323181e-01,
        6.24431305e-01,
        1.25871938e00,
        9.73003775e-01,
        1.83284056e00,
        7.67068188e-01,
        2.16195802e00,
        1.97370305e00,
        7.27160897e-01,
        -9.71488218e-01,
        -8.58690312e-01,
        -3.67525205e-01,
        1.29494233e00,
        7.18195673e-02,
        1.21326802e00,
        -7.58598785e-01,
        -1.06418506e-03,
        -3.60541127e-01,
        5.97630287e-01,
        1.16314252e00,
        2.79888774e00,
        3.17366401e00,
        8.46983160e-01,
        1.71412642e-02,
        -5.94253205e-01,
        1.10030645e-01,
        8.48605322e-01,
        1.60590771e00,
        1.51386287e00,
        -7.66986890e-01,
        3.71606231e-01,
        9.31114992e-01,
        1.14051595e00,
        3.12671250e00,
        8.41910255e-01,
        1.81572098e00,
        7.26485448e-01,
        9.54109141e-01,
        -7.01049465e-01,
        -7.08966723e-01,
        1.84269535e00,
        2.23904728e00,
        1.04671627e00,
        3.85234747e-02,
        -4.04382967e-01,
        7.65336840e-01,
        7.72256692e-01,
        1.39904849e00,
        1.49380494e00,
        1.02689147e00,
        7.66556348e-01,
        6.45355391e-01,
        5.92087646e-01,
        1.45512657e00,
        8.99221323e-01,
        2.24730476e00,
        1.83258046e00,
        1.76767850e00,
        -8.32995347e-02,
        1.43100675e00,
        1.42191705e-01,
        2.27576545e00,
        3.39549232e00,
        3.35252919e00,
        1.48749067e00,
        -1.17012953e00,
        -6.15039264e-01,
        9.25848706e-01,
        8.39612122e-01,
        3.49473756e00,
        3.62672699e00,
        7.11679401e-01,
        -6.21133647e-01,
        -1.71974130e-01,
        2.19582351e-01,
        1.70029203e00,
        4.97072898e-01,
        3.07661373e00,
        5.89705127e-01,
        -3.85557180e-01,
        -1.21627747e-01,
        6.88094658e-01,
        2.08683855e00,
        2.04800796e00,
        3.67022420e-01,
        3.03847578e-02,
        2.12803068e-01,
        1.27382824e00,
        2.20525878e00,
        2.09729942e00,
        2.92745219e00,
        1.43501329e00,
        -1.00158984e00,
        -4.26869441e-01,
        2.38459396e-01,
        6.18281003e-01,
        2.86900336e00,
        5.26441897e-01,
        1.83471736e00,
        5.64276032e-01,
        -4.79185498e-02,
        1.56645081e00,
        1.90975688e00,
        1.96805054e00,
        1.32437211e00,
        1.54723551e00,
        2.97027599e00,
        8.23747319e-01,
        -1.07597824e00,
        1.29796781e-01,
        3.08261173e00,
        1.94024883e00,
        1.67053036e00,
        7.68453719e-01,
        2.53848214e-01,
        -2.71074406e-01,
        1.11041190e00,
        3.06171371e00,
        2.88915244e00,
        2.00362771e00,
        1.67907635e00,
        9.25318467e-01,
        -6.21558807e-01,
        3.77295621e-01,
        2.51130485e00,
        1.23662523e00,
        1.47239092e00,
        1.17058209e00,
        1.47667951e-01,
        1.33386697e-01,
        -4.53263981e-01,
        1.12631733e00,
        3.26298892e00,
        2.35568468e00,
        3.83027496e-01,
        -3.78093690e-02,
        6.37261226e-01,
        1.72890857e00,
        2.57274809e00,
        2.60905435e00,
        1.56994909e00,
        5.17535191e-01,
        3.77275665e-01,
        -3.45929860e-01,
        2.58949535e00,
        7.62669260e-01,
        3.47958346e00,
        1.83376087e00,
        3.34759101e-01,
        -1.39156268e-01,
        1.24690335e-01,
        1.07593646e00,
        1.77047871e00,
        1.18853328e00,
        8.68015144e-01,
        8.48988929e-01,
        -8.95110881e-01,
        1.07420642e-01,
        3.06363479e00,
        7.15866469e-01,
        1.66342966e00,
        2.57150732e00,
        -1.04277245e-01,
        -2.90886083e00,
        -1.00809760e00,
        7.93375194e-01,
        2.20504948e00,
        2.85967791e00,
        2.15743733e00,
        2.08510982e00,
        3.16493745e-01,
        -1.04790522e00,
        1.30076686e-01,
        1.47648939e00,
        9.65983115e-01,
        3.03133713e00,
        -2.24802033e00,
        -1.90839207e-01,
        1.41532791e00,
        7.77675677e-01,
        2.91494777e00,
        2.70474727e00,
        2.01074236e00,
        1.30244225e00,
        -4.91068641e-01,
        4.32498323e-01,
        1.95233060e00,
        3.07520214e00,
        3.78334096e00,
        3.35590562e00,
        -8.08053405e-01,
        4.51994781e-01,
        7.74504797e-01,
        3.52334793e-01,
        2.44854135e00,
        3.34811742e00,
        1.82352584e00,
        2.26330255e00,
        2.77269351e-01,
        6.07576157e-02,
        -2.01833711e-01,
        1.04185052e00,
        2.32538242e00,
        2.84038167e00,
        2.29044210e00,
        7.03146152e-01,
        -6.01907112e-01,
        1.80397234e00,
        1.98634086e00,
        1.22690644e00,
        3.21915541e00,
        -1.17284206e00,
        -1.54417786e00,
        9.18351626e-01,
        1.76980729e00,
        1.04351305e00,
        2.36195029e00,
        1.16500774e00,
        6.12450462e-01,
        -7.08609723e-01,
        1.04230824e00,
        1.70969447e00,
        2.64288913e00,
        2.34976952e-01,
        1.18716059e00,
        -6.61424108e-02,
        -1.20049369e00,
        -1.12993788e-01,
        7.55088949e-01,
        1.83416312e00,
        2.91320098e00,
        2.24328733e00,
        2.40555340e00,
        -8.20700873e-01,
        -2.63662670e-01,
        2.94146708e00,
        1.04753337e00,
        2.53330830e00,
        2.32237327e00,
        3.59879157e00,
        -8.70552383e-02,
        -1.59399066e00,
        5.19713176e-01,
        2.12543089e00,
        6.33612253e-01,
        6.34693702e-03,
        5.60397860e-01,
        1.11221859e00,
        5.75088199e-01,
        1.47442294e00,
        1.57493470e00,
        2.26755516e00,
        1.01931474e00,
        8.58035549e-01,
        6.32568766e-02,
        -9.93171533e-02,
        9.53238163e-01,
        -7.85355122e-02,
        2.21938966e00,
        -7.07804875e-01,
        1.67680863e00,
        -6.63675108e-01,
        8.64217983e-02,
        6.97749258e-01,
        1.31259744e00,
        2.59287989e00,
        1.56744990e00,
        7.89167355e-01,
        1.81647380e00,
        7.08114108e-02,
        4.20118710e-01,
        2.17202561e00,
        2.82122287e00,
        3.27621088e00,
        6.30451516e-01,
        9.99653246e-01,
        1.30341376e00,
        5.29974172e-01,
        2.89059099e00,
        1.37370641e00,
        1.23284225e00,
        9.20544746e-02,
        -2.13971697e00,
        6.64817992e-02,
        4.62250775e-01,
    ]
)

After zooming in a few times, it looks something like this:

┌────────────────────────────────────────────────────────────┐
│▐  ▐  █ ▐  ▖ ▟▟ █ ▐█    ▌    ▐▌▐▐    ▌▌▐▐ ▌ ▙▌ ▐ ▌▐ ▌▌▐▐▌▐  │ 1.7
│▐▐ ▐  █ ▐  ▌ ██ ▌▌▐▛▖   ▌  ▌ ▐▌▐▐    ▌▌▐▐ ▌ █▌ ▐ ▌▐▌▌▌▌▐▌▐▌▐│ 
│▐▐ ▐  █▖▐▙ █ ██ ▌▌▐▌▌   ▌  █ ▐▌▐▐ ▐ ▗▌▙▐▐ ▌ ▜▌ ▐ ▌▐▌▌▌▌▐▌▌▚▐│ 
│▐▐ ▐▚ █▌▞█ █ ██ ▌▌▐▌▌▗  ▌  █ ▐▌▐▐ ▐▌▐▌█▟▐ ▌▖▐▌ ▐ ▙▐▌▙▌▌▞▚▌▐▐│ 
│█▝ ▐▐ █▌▌█ █▌██ ▌▌█▌▌▐▌▐▌  █ ▟▌▐▐ ▌▌▐▌██▐ ▌▌▐▌ ▐ █▐▌█▌▌ ▐▌█▐│ 1.2
│█  ▐▐ █▌▌█ █▌▛█▐ █▌▌▌▐▙ ▌ ▐▐▐▐▌▐▐ ▌▌▐▌█▛▐ █▌▐▌ ▝▌█▐▌██▌▌▐▌█▐│ 
│█  ▐▐ ██▌▜ █▌▌▜▐ █▘▌▌▐█ ▌ ▐▐▐▐█▐▐▖▌▚▐▌█▌▐▐█▌▐▌  ▌█▐▌██▌▌▐▌█▐│ 
│█ ▐▐▐ ██▌▐ █▌▌▐▐▗█ ▌▌▐█ ▌▌▟▐▐▝▐▐▐▙▌▐▞ █▌▐▐▜▌▐▙  ▌█▐▌█▜▌▌▐▌█▐│ 
│█ ▐▐▝▖██▌▐ █▌▌▐▐▝█ ▌▌▐█▐ ▚▜▐▞ ▐▐▐█ ▝▌ █▌▐▐▐▌▐█ ▌▌█▐▘█▐▌▌▐▌█▐│ 0.6
│█ ▐▐ ▌██▌▐ █▌▌▐▐ ▌ ▌▌▐█▐ ▐▐▐▌ ▝▟▐█    ▜▌▐▐▐▌▐█▐▌▙▜▐ █▐▌▌▐▌▀▟│ 
│█ ▐▐ ▌██▌▐ █▌▌▐▐   ▌▌▐█▐ ▐▐▐▌  █▝█    ▐▌▐▐▐▌▐ █▌█▐▐▐ ▐▌▌▐▌ █│ 
│█▐▐▐ ▚██▌▐▐▛▌▌▐▐   ▌▌▞█▐▐▐▐▐▌  █ █    ▐▌▐▐▐▐▌ █▘█▝▐▐ ▐▌▌▐▌ █│ 
│█▝▟▐ ▐██▌▐▐▌▌▌▐▐   ▌▙▌█▐▐▐▞▐▌  █ █▗   ▐▘▖█▐▐▌▐█ █ ▐▐ ▐▌▌▐▌ █│ 0.1
│▌▔█▐▔▐▜█▌▐▐▔▌▙▐▐▔▔▔▔█▌▐█▐▐▌▐▌▔▔█▔█▐▔▔▔▐▔▌█▐▐▌▐█▔▌▔▐▐▔▝▌▌▐▌▔█│ 
│▌ █▌ ▐▐█▌▐▐ █▐ ▌    █▌▐█▐▐▌▐▌  █ █▐     ▌█▐▐▌ █ ▌ ▐▐   ▌▐▌ █│ 
│▌ █▌ ▝▝█▌▐▐ █▐ ▌    █▌▐█▐▐▌▐▌  █ ▛▐     ▌█▐▐▘ ▌ ▘ ▐▞   ▌▐▌ ▝│ 
│▌ █▌   █▌▐▐ █▐ ▌    ▐▌▐▘▐ ▌▐▌  █ ▌▐      █▐▐  ▘   ▝▌   ▘▐▌  │ -0.5
└────────────────────────────────────────────────────────────┘
 168                                                      332
Move h/j/k/l, zoom u/n, or r to reset. ESC/q to quit
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/olav/Desktop/Development/uniplot/uniplot/uniplot.py", line 48, in plot
    xs=series.xs, ys=series.ys, options=options
  File "/Users/olav/Desktop/Development/uniplot/uniplot/layer_assembly.py", line 24, in assemble_scatter_plot
    pixel_layer = layer_factory.render_points(xs=xs, ys=ys, options=options)
  File "/Users/olav/Desktop/Development/uniplot/uniplot/layer_factory.py", line 75, in render_points
    lines=options.lines,
  File "/Users/olav/Desktop/Development/uniplot/uniplot/pixel_matrix.py", line 125, in render
    # DEBUG
IndexError: index -167 is out of bounds for axis 1 with size 120

Use different characters instead of colors

Is is possible to use different characters instead of colors for plotting multiple series?

It would be nice because I use this library for plotting, and then redirect the python script output to a file, which obviously loses the concept of color, so using like "*" and "+" instead of colors you be nice

Requesting Support for Plotting Line Graphs

Hi Olav. Appreciate the great work with this project. Found this quite useful in logging some data graphically to the terminal in a few of my Data Science projects.
Here is a recommendation for a new feature that can be added. I understand that there is currently support for plotting Scatter Plots and Histograms in Uniplot. Would be great if support for plotting Line Graphs was also added to visualize the trend of data. Kindly look into the possibility of doing this.
Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.