piccolomo / plotext Goto Github PK
View Code? Open in Web Editor NEWplotting on terminal
License: MIT License
plotting on terminal
License: MIT License
There is another problem, if i want to plot a datastream that only contains zeros it throws an exception and not plotting anything.
I tried this:
plx.scatter([0,0,0])
plx.show()
and got this:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files\Python37\lib\site-packages\plotext\plot.py", line 48, in show
_set_grid()
File "C:\Program Files\Python37\lib\site-packages\plotext\plot.py", line 324, in _set_grid
_add_to_grid(_vars.x[s], _vars.y[s], _vars.point_marker[s], _vars.point_color[s])
File "C:\Program Files\Python37\lib\site-packages\plotext\plot.py", line 350, in _add_to_grid
r = int((y[n] - _vars.ymin) / _vars.dy)
ZeroDivisionError: float division by zero
If I set the ylim to something this issue does not occur.
This looks a very cool library! While testing histogramming I get this output from the example script
(on my mac terminal)
any ideas of why is that?
I ask because some time ago I implemented something similar for vedo
and it has the same problem:
from vedo import printHistogram
import numpy as np
d = np.random.normal(size=1000)
printHistogram(d, c='lb', logscale=True, title='my scalars')
printHistogram(d, c='red', horizontal=1)
it would be nice to ditch my old implementation in favour of plotext
.
Hi - first of all, this terminal plotter is awesome! Thanks for the effort!
I noticed that with a single plot, the plot will only resize if the terminal is made smaller - if the terminal is made larger, the plot doesn't become larger with it.
I think the issue with your latest refactor is that you're missing a couple of lines in plotsize():
def plotsize(width = None, height = None):
width, height = _ut.set_first_to_both(width, height)
width, height = _ut.set_list_to_both(width, height)
_fig.subplot.width = width
_fig.subplot.height = height
there maybe should be the two additional lines below?
def plotsize(width = None, height = None):
width, height = _ut.set_first_to_both(width, height)
width, height = _ut.set_list_to_both(width, height)
_fig.width = width
_fig.height = height
_fig.subplot.width = width
_fig.subplot.height = height
Was wondering how easy/hard would be to integrate your project with rich : >
Currently subplots functionality seems broken, even README
example do not work. Specifically, only first plot appears.
It would be nice to return the string value of the equivalent terminal plot.
If you try to produce a bar plot with a value of zero in index 0 of the values list, the plot will fail with an error. Here is an example:
>>> values = [0, 93, 160, 120, 35, 0, 0, 0, 0, 0, 0, 0]
>>> import plotext as plt
>>> plt.clp()
>>> plt.bar(labels,values)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.9/dist-packages/plotext/plot.py", line 954, in bar
_fig.subplot.point_color[-1] = _fig.subplot.point_color[-2]
IndexError: list index out of range
If you remove the first element of each list above though, every thing works ok.
>>> labels = ['[64-127]', '[128-255]', '[256-511]', '[512-1023]', '[1024-2047]', '[2048-4095]', '[4096-8191]', '[8192-16383]', '[16384-32767]', '[32768-65535]', '[65536-131071]']
>>> values = [93, 160, 120, 35, 0, 0, 0, 0, 0, 0, 0]
>>> plt.clp()
>>> plt.bar(labels,values)
>>> plt.show()
<shows graph>
The bar plot should be able to produce a plot when the first value in the list of values is zero. If you need any additional information from me regarding this issue, please let me know. Thanks.
Sometimes, the data returned from the server has '0' for all day and night counts. When plotting, this results in a ZeroDi
visionError exception:
>>> import plotext as plt
>>> dates = ['2022-01-01', '2022-01-02', '2022-01-03']
>>> dayc = [0, 0, 0]
>>> nightc = [0, 0, 0]
>>> plt.bar(dates, dayc)
>>> plt.show()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_figure.py", line 285, in show
self.build()
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_figure.py", line 269, in build
self.subplot.get_relative_ticks()
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_subplot.py", line 285, in get_relative_ticks
self.rticks = self._get_relative_ticks(self.yticks, self.ylim, self.height_canvas)
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_subplot.py", line 291, in _get_relative_ticks
ticks = [get_matrix_data(ticks[s], lim[s], bins) for s in range(2)]
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_subplot.py", line 291, in <listcomp>
ticks = [get_matrix_data(ticks[s], lim[s], bins) for s in range(2)]
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_utility/plot.py", line 29, in get_matrix_data
data = [round((el - lim[0]) / dz + 0.5, 1) for el in data] if lim[0] != None else [None] * len(data)
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_utility/plot.py", line 29, in <listcomp>
data = [round((el - lim[0]) / dz + 0.5, 1) for el in data] if lim[0] != None else [None] * len(data)
ZeroDivisionError: float division by zero
>>> plt.stacked_bar(dates, [dayc, nightc])
>>> plt.show()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_figure.py", line 285, in show
self.build()
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_figure.py", line 269, in build
self.subplot.get_relative_ticks()
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_subplot.py", line 285, in get_relative_ticks
self.rticks = self._get_relative_ticks(self.yticks, self.ylim, self.height_canvas)
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_subplot.py", line 291, in _get_relative_ticks
ticks = [get_matrix_data(ticks[s], lim[s], bins) for s in range(2)]
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_subplot.py", line 291, in <listcomp>
ticks = [get_matrix_data(ticks[s], lim[s], bins) for s in range(2)]
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_utility/plot.py", line 29, in get_matrix_data
data = [round((el - lim[0]) / dz + 0.5, 1) for el in data] if lim[0] != None else [None] * len(data)
File "/Users/barbe/Projects/installer_tools/.venv/lib/python3.9/site-packages/plotext/_utility/plot.py", line 29, in <listcomp>
data = [round((el - lim[0]) / dz + 0.5, 1) for el in data] if lim[0] != None else [None] * len(data)
ZeroDivisionError: float division by zero
First, I love the program!
I have been able to use plotext to plot to a tkinter text widget. It works well, but is totally dependent on the terminal size that the user happens to be using at runtime.
Would it be possible to add a flag to ignore the actual terminal size and force it to, let's say 80x24, so that when the plot is generated (hidden and saved to file) can be sent directly to the tkinter text widget?
Thank you in advance for your consideration.
Greg
I've been trying to run the example code provided in the README for the hist function:
import plotext as plt
import random
data = [random.gauss(0, 1) for el in range(50000)]
data2 = [random.gauss(3, 1) for el in range(50000)]
plt.clp()
bins = 60
plt.hist(data, bins, label="mean 0")
plt.hist(data2, bins, label="mean 3")
plt.title("Histogram plot")
plt.xlabel("data bin")
plt.ylabel("frequency")
plt.figsize(100, 30)
plt.show()
I get the following error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-e704a9ff5ccd> in <module>
11 plt.ylabel("frequency")
12 plt.figsize(100, 30)
---> 13 plt.show()
~/anaconda3/envs/pepys_py38/lib/python3.8/site-packages/plotext/plot.py in show()
335 _size_max()
336
--> 337 _height_min()
338 _height()
339
~/anaconda3/envs/pepys_py38/lib/python3.8/site-packages/plotext/plot.py in _height_min()
372 def _height_min():
373 par.height_title = int(par.title != "")
--> 374 par.height_xaxis = int(par.axes[0] or par.frame)
375 par.height_xticks = bool(par.ticks[0])
376 par.height_labels = int(par.xlabel != "" or par.ylabel != "")
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
It seems like par.axes[0]
or par.frame
aren't initialised properly? Do you have any idea how to fix this?
Hi,
The DateTime plot plot_date
requires all values to be numeric (None/NaN/np.nan is not accepted), but it's useful to be able to display shorter lines that don't span the whole time frame, which requires a way to represent no data like None/NaN. What I'm trying to do is to add some arbitrary trend line/channel on a stock price series.
Can you support this?
Thanks!
I tried this with python(3) running in a windows PowerShell terminal.
It just produces a lot of strange control characters and beeping (probably the line-end bell) for a while and then stops.
I assume it's not compatible with this type of output terminal.
Might be worth a warning in the documentation/readme.
Or did I do something wrong?
Test was:
import plotext as plx
y = [1, 2, 3, 4, 5]
plx.plot(y)
plx.show()
Windows 7
Python 3.8.8 (installed via WinPython)
plotext 2.3.1 (installed via pip)
The resulting plot is the minimum of the current terminal and the defined plotsize
regardless of the status of hide
. I think that it would make more sense to use only plotsize when hide=True
.
My plots are all showing up with s
's on macOS rather than the small character, which I'm sure the terminal supprorts. I'm not sure why, looking into the code, as the platform should be set to "linux" as far as I can tell. However, I noticed a few things that made it hard to parse and debug the code:
_plot
, for example?import *
should be avoided in a library. You only have one, so that's not too bad; but two or more make it really hard to track things down.sudo pip
(in the readme). Recent versions of pip will install into the user location if the system location is not writable (but, hopefully, all users will be in virtual environments). Pip literally prints a warning if it can detect you are running it with sudo, because it will break your system. Could you touch up the README suggestion?Hopefully these points are helpful. :) You might find the guide here https://scikit-hep.org/developer helpful for PyTest and nice packaging / checks. Anyway, the main problem is my "small" marker plots have only s's.
When trying to execute the command line example (or any other code that worked in previous version) the following error appears:
python3 -c "import plotext as plt; y=plt.sin(); plt.clp(); plt.scatter(y); plt.title('Scatter Plot'); plt.show();"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/tmp/plotext/.venv/lib/python3.8/site-packages/plotext/__init__.py", line 3, in <module>
from plotext._core import *
File "/tmp/plotext/.venv/lib/python3.8/site-packages/plotext/_core.py", line 14, in <module>
from plotext._figure import figure_class as _figure_class
File "/tmp/plotext/.venv/lib/python3.8/site-packages/plotext/_figure.py", line 9, in <module>
from plotext._subplot import subplot_class
File "/tmp/plotext/.venv/lib/python3.8/site-packages/plotext/_subplot.py", line 7, in <module>
from plotext._utility.image import *
File "/tmp/plotext/.venv/lib/python3.8/site-packages/plotext/_utility/image.py", line 2, in <module>
from PIL.Image import fromarray
ModuleNotFoundError: No module named 'PIL'
It also happens with Python 3.9.
...
165 plt.ylabel(k2)
166
--> 167 plt.show()
168
169
plotext/plot.py in show(hide)
432 _ylim_data(subplot)
433 _ylim_plot(subplot)
--> 434 _yticks(subplot)
435
436 _width(subplot)
plotext/plot.py in _yticks(subplot)
564 if subplot.yscale[0] == "linear":
565 subplot.yticks_left = _utility.get_ticks(subplot.ylim_plot_left, subplot.ticks[1])
--> 566 subplot.ylabels_left = _utility.get_labels(subplot.yticks_left)
567 if subplot.yscale[0] == "log":
568 subplot.yticks_left, subplot.ylabels_left = _utility.get_log_ticks(subplot.ylim_plot_left, subplot.ticks[1])
plotext/utility.py in get_labels(ticks)
122 else:
123 c = max([distinguish(ticks[i], ticks[i + 1]) for i in range(l - 1)])
--> 124 ticks = [round_to_character(el, c) for el in ticks]
125 # ticks = [int(el) if int(el) == el else el for el in ticks]
126
plotext/utility.py in <listcomp>(.0)
122 else:
123 c = max([distinguish(ticks[i], ticks[i + 1]) for i in range(l - 1)])
--> 124 ticks = [round_to_character(el, c) for el in ticks]
125 # ticks = [int(el) if int(el) == el else el for el in ticks]
126
plotext/utility.py in round_to_character(n, c)
148 if d < 0:
149 d = 0
--> 150 return round(n, d)
151
152
TypeError: type numpy.ndarray doesn't define __round__ method
content of subplot
╭────────────── <class 'plotext.plot._subplot'> ───────────────╮
│ ╭──────────────────────────────────────────────────────────╮ │
│ │ <plotext.plot._subplot object at 0x7f7b77aa0940> │ │
│ ╰──────────────────────────────────────────────────────────╯ │
│ │
│ axes_color = 'none' │
│ canvas_color = 'none' │
│ col = 0 │
│ data = True │
│ data_left = True │
│ data_right = False │
│ fillx = [False, False, False, False, False] │
│ filly = [False, False, False, False, False] │
│ grid = [False, False] │
│ height = 22 │
│ height_canvas = 17 │
│ height_max = 22 │
│ height_set = 30 │
│ label = ['', '', '', '', ''] │
│ label_show = [True, True, True, True, True] │
│ line_color = ['lilac', 'green', 'none', 'none', 'none'] │
│ line_marker = ['small', '▁', '', '', ''] │
│ point_color = ['none', 'none', 'none', 'tomato', 'blue'] │
│ point_marker = ['', '', '•', '•', '•'] │
│ row = 0 │
│ signals = 5 │
│ signals_left = 5 │
│ signals_right = 0 │
│ ticks = [5, 7] │
│ ticks_color = 'none' │
│ title = 'Beginning' │
│ width = None │
│ width_set = 100 │
│ x = [ │
│ [ │
│ 3.0, │
│ 3.0393939393939395, │
│ 3.0787878787878786, │
│ 6.387878787878789, │
(Edited by Savino: removed the long list of data, to facilitate reading)
│ ], │
│ [1.6, 1.5, 1.3, 1.3, 1.4], │
│ [1.4, 1.8, 1.8, 2.1, 2.1] │
│ ] │
│ y_right = [] │
│ yaxes = [True, True] │
│ yaxis = ['left', 'left', 'left', 'left', 'left'] │
│ ylabel = ['PetalWidthCm', ''] │
│ ylabels_left = [] │
│ ylabels_right = [] │
│ ylim_data_left = [array([0.84001974]), 2.5] │
│ ylim_data_right = [-1, 1] │
│ ylim_plot_left = [array([0.84001974]), 2.5] │
│ ylim_plot_right = [-1, 1] │
│ yscale = ['linear', 'linear'] │
│ yticks_left = [] │
│ yticks_right = [] │
╰──────────────────────────────────────────────────────────────╯
I'd like to explain my use case:
Pillow and especially numpy are pretty heavy dependencies. Numpy is ~63 MB and Pillow is ~10 MB. In the context of my project this is a significant size.
I was wondering if you'd consider making Pillow and numpy optional dependencies that could be installed only if using the image graphing features? I think this could be done by moving the library imports so they are only called when that code path that needs them is executed. And then marking Pillow and numpy as optional dependencies in setup.py (or I could work around this with pip install --no-deps
).
If you plan to incorporate numpy into more features in the future, making plotext more dependent on it, then my request wouldn't make much sense to do.
This library looks great, and I'm starting to use it in my project.
As well as doing line plots, I was hoping to do horizontal bar charts that look a bit like the following (although ideally with axis ticks and so on as well):
Foo #########
Bar ####
Baz ###########
I was hoping this would be a fairly simple modification of the existing hist
command (as this is basically a simplified version of a histogram), but it looks like it's more complicated than that, as we need separate labels for each of the categories. I've also had an issue running the hist
example code (see #15).
Also, is the code available fully in the Github repository? When I clone the repository, the plotext
folder seems to be a submodule, but I can't seem to retrieve the contents of the submodule. Could you let me know what git commands I need to run to get hold of the full code? (At the moment, I'm browsing the code in the folder that pip installed it to, which is not ideal). I've got a small PR I'd like to submit, but I can't work out how to submit it if I can't get full access to the code in Git.
Hey there!
I'd like to simulate a stem plot. For that I think the easiest way might be using a regular scatter plot in combination with multiple vertical lines. However, I'm not sure how to draw those straight lines. Any ideas?
PS: This is really an awesome project. Keep it up!
Hi,
Thanks for this library. I need to draw stacked and multiple bars, for that I have written some wrappers around your library:
For multiple bars:
def ParBar(*args,
yaxis="left",
label="",
marker="small",
color=None,
fill=True,
width=4 / 5,
orientation='vertical'):
if len(args) == 0:
x, y = [], []
elif len(args) == 1:
y = np.array(args[0], dtype=float)
x = list(range(y.shape[1]))
else:
x = args[0]
y = np.array(args[1], dtype=float)
shape = y.shape
# enough colors for every graph
if color is not None:
if len(color) != len(y):
raise ValueError(
"If color parameters is given, one color for every series is mandatory")
else:
color = [None] * len(y)
# or single marker (enough for color plots) or one for every series (for monochrome)
if isinstance(marker, str):
marker = [marker] * len(y)
elif len(marker) != len(y):
raise ValueError(
"If more than one marker is given, one for every series is mandatory")
# or single label (enough for color plots) or one for every series (for monochrome)
if isinstance(label, str):
label = [label] * len(y)
elif len(label) != len(y):
raise ValueError(
"If more than one label is given, one for every series is mandatory")
for idx, series in enumerate(y):
plt.bar(np.arange(shape[1]) + idx/shape[0], list(series), yaxis=yaxis, label=label[idx],
marker=marker[idx], color=color[idx], fill=fill, width=width/shape[0], orientation=orientation)
plt.xticks(np.arange(shape[1]) + 1/2 - 1/(2 * shape[0]), x)
The cities bar example ends being:
cities = ["Tokyo", "Delhi", "Shanghai", "São Paulo",
"Mexico City", "Cairo", "Mumbai", "Beijing"]
population = [37400068, 28514000, 25582000,
21650000, 21581000, 20076000, 19980000, 19618000]
dogs = [3740006, 2851400, 2558200, 4165000, 3158100, 2007600, 1998000, 1961800]
plt.plotsize(100, 40)
plt.title("Bar Plot of the World Largest Cities")
plt.xlabel("City")
plt.ylabel("Population")
ParBar(cities, [population, dogs], width=.5)
For stacked bars:
def StackedBar(*args,
yaxis="left",
label="",
marker="small",
color=None,
fill=True,
width=4 / 5,
orientation='vertical'):
if len(args) == 0:
x, y = [], []
elif len(args) == 1:
y = np.array(args[0], dtype=float)
x = list(range(y.shape[1]))
else:
x = args[0]
y = np.array(args[1], dtype=float)
final_series = np.zeros((y.shape))
# enough colors for every graph
if color is not None:
if len(color) != len(y):
raise ValueError(
"If color parameters is given, one color for every series is mandatory")
else:
color = [None] * len(y)
# or single marker (enough for color plots) or one for every series (for monochrome)
if isinstance(marker, str):
marker = [marker] * len(y)
elif len(marker) != len(y):
raise ValueError(
"If more than one marker is given, one for every series is mandatory")
# or single label (enough for color plots) or one for every series (for monochrome)
if isinstance(label, str):
label = [label] * len(y)
elif len(label) != len(y):
raise ValueError(
"If more than one label is given, one for every series is mandatory")
# Add height to previous one, with numpy simpler, but done iterating to avoid extra libraries
for idx, series in enumerate(y):
if idx > 0:
final_series[idx] = series + final_series[idx-1]
else:
final_series[idx] = series
# Must print in reverse, so that bigger stacks are printed first
for idx, series in enumerate(final_series[::-1]):
plt.bar(list(x), list(series), yaxis=yaxis,
label=label[idx], marker=marker[idx], color=color[idx], fill=fill, width=width, orientation=orientation)
An example of the cities in stacked mode is:
cities = ["Tokyo", "Delhi", "Shanghai", "São Paulo",
"Mexico City", "Cairo", "Mumbai", "Beijing"]
population = [37400068, 28514000, 25582000,
21650000, 21581000, 20076000, 19980000, 19618000]
dogs = [3740006, 2851400, 2558200, 4165000, 3158100, 2007600, 1998000, 1961800]
plt.plotsize(100, 40)
plt.title("Bar Plot of the World Largest Cities")
plt.xlabel("City")
plt.ylabel("Population")
StackedBar(cities, [population, dogs] )
If you think it may be interesting to include this functions in your code, happy to help.
This works as expected (all x values are show even if the y-value is 0):
python3 -c "import plotext as plt; plt.bar([1,2,3],[1,0,1]); plt.show()"
If there is a 0 value at the beginning of the array it causes IndexError:
python3 -c "import plotext as plt; plt.bar([1,2,3],[0,1,1]); plt.show()"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.9/dist-packages/plotext/plot.py", line 954, in bar
_fig.subplot.point_color[-1] = _fig.subplot.point_color[-2]
IndexError: list index out of range
If there is a 0 value at the end of the array it is not shown in the bar chart:
python3 -c "import plotext as plt; plt.bar([1,2,3],[1,1,0]); plt.show()"
Hi,
Thanks for this great tool. I think that plotext could shine even more by quickly plotting data from files and stdin. I wrote a small python script that allows me to plot from a pipe
$ ./process_data data.txt | plotext 1,3 # use first and third column
┌─────────────────────────────────────────────────────────────────────────────────────────┐
21.0┤ ▝│
│ │
│ │
18.0┤ │
│ │
│ │
15.0┤ │
│ ▖ │
│ │
11.0┤ │
│ │
│ ▝ │
│ │
8.0┤ ▗ │
│ │
│ │
4.0┤ ▝ │
│ │
│ ▖ │
1┤▞ │
└┬─────────────────────┬─────────────────────┬─────────────────────┬─────────────────────┬┘
1 33.0 64.0 96.0 128
@piccolomo, if you think this could be a good idea, I can provide a patch. If so, we should agree on the interface. I was thinking to ship an executable plotext
that can quickly plot data from files and stdin like gnuplot does, but better :)
plotext data.txt --type scatter --columns 1,3 1,5
cat data.txt | plotext --pipe --type scatter --columns 1,3 1,5
I ran into the exact same issue described in this question. TL;DR - when running this library in PyCharm, the error in the subject is thrown by utility.py>terminal_size()>os.get_terminal_size()
.
One of the fixes proposed in the Q&A worked for me, so I suggest replacing
-return list(os.get_terminal_size())
+return shutil.get_terminal_size(fallback=(120, 50))
Or if you want to keep the existing code and provide a fallback,
-def terminal_size():
- return list(os.get_terminal_size())
+import shutil
+ ...
+def terminal_size():
+ try:
+ return list(os.get_terminal_size())
+ except OSError:
+ return shutil.get_terminal_size(fallback=(120, 50))
Thanks!
P.S. I'm using Python 3.6 on Ubuntu 16.04 with PyCharm 2021.2.
First of all, your lib is awesome : )
As a side-project, I'm working on a multi-format plotting utility, and your lib was an obvious first choice for the text output.
It's possible that I'm doing something wrong, but ylim/xlim seems to be set by the last histogram plot, and not the highest. Both scatter and line plots work well.
Hi,
maybe I missunderstood the manual, but I expect a plot from x = 1 to 10 and values y from 1 to 100.
import plotext as plx
x=[1,2,3,4,5,6,7,8,9,10]
y=[i**2 for i in x]
plx.scatter(x,y)
plx.show()
however I get a plot like the this one.
•├45
│
│
│
│
├40
│
│
│
• │
├35
│
│
│
│
├30
• │
│
│
│
├25
│
│
• │
│
├20
│
│
│
• │
├15
│
│
│
• │
├10
│
│
• │
│
├5
• │
│
│
• │
• ├0
┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬──────┘
0 10 20 30 40 50 60 70 80 90 100 110
The (x,y)-pairs are not matching with the labels on the axes.
What I'm doing wrong?
>>> plx.__version__
'1.0.11'
>>> sys.version
'3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AMD64)]'
Bye, Uwe
Miminal example:
plt.bar(["a"],[1])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/jfrejlac/school/PDI/project/venv/lib64/python3.9/site-packages/plotext/_core.py", line 197, in bar
figure.subplot.draw_single_bar(x, y,
File "/home/jfrejlac/school/PDI/project/venv/lib64/python3.9/site-packages/plotext/_subplot.py", line 429, in draw_single_bar
xbar, ybar = bars(x, y, width, self.bar_ylim[0])
File "/home/jfrejlac/school/PDI/project/venv/lib64/python3.9/site-packages/plotext/_utility/bar.py", line 54, in bars
bin_size_half = (max(x) - min(x)) / (bins - 1) * width / 2
ZeroDivisionError: division by zero
Wanted to say that I love this library and it has been super useful!
I am interested in helping add datetime support for the x-axis if it's something you're interested in. The particular case I'm thinking of is using a pandas Series with a datetime index. I haven't had a chance to dig into the source code yet, but was hoping to gauge interest in this kind of support and perhaps get pointers for where to start looking in the code. It seems like the x-axis must be integer based, which I assume is due to methods in place that scale the x-axis to fit into 80 lines. Hopefully I'll have time to get a better grasp of the ins and out of the code soon, but it would be great if we could work towards datetime-oriented axes.
If I've somehow missed the fact that this is possible with the library as is, please forgive me: I've only had a few days with the library.
Thanks!
When using plt.build, the size is dependent on the terminal. It may be more useful to only depend on plt.plotsize.
I was confused by a strange index out of bound error
File "xxxxx/terminal-plot/lib/python3.9/site-packages/plotext/_figure.py", line 55, in set_subplot
self.subplot = self.subplots[self.row][self.col]
IndexError: list index out of range
which, after some extensive investigation I realise it's due to
Line 41 in db4bb95
and the defaults is defined in
Line 6 in db4bb95
I don't oppose sane defaults (it should probably be configurable). However, this override is undetectable from user code as it is enforced in figure creation without any notice. In my opinion, it might be better off throw an exception instead of silently overrides the subplot size...
I found a strange bug, that when you run plx.show()
multiple times,
the view is changed and not plotted the same each time.
I tried following scenario:
plx.scatter([10,2,3,5,2,1,5,13,4,2,5,3,2,1,5,6,17,12,15,4,5,4,3,2,5,6,9,8,12,18,5,3,2],rows=10,cols=25,point_color="red",equations=True)
plx.show()
plx.show()
plx.show()
I get:
• │
• │
• │
• • • │
• ├5
• │
• • │
• •• • • ••• • • │
••• ••• • ••│
• • ├0
┬─────────┬─────────┬────┘
0 10 20
x = 1.33 × col - -0.00 ± 0.67
y = 1.89 × row + 1.00 ± 0.94
• │
• │
• │
• • • │
• ├5
•• │
• • │
• •• • • ••• • • │
••• ••• •• ••│
• • ├0
┬─────────┬─────────┬────┘
0 10 20
x = 1.39 × col - -0.67 ± 0.69
y = 2.10 × row + 0.06 ± 1.05
│
• • │
• │
• • • │
• ├5
•• │
• • • • • • • │
• • • ••• • │
• • • •• • • │
├0
┬─────────┬─────────┬────┘
0 10 20
x = 1.45 × col - -1.36 ± 0.72
y = 2.33 × row - -0.99 ± 1.17
If I continue it eventually looks like:
│
│
│
│
••• ├5
••• │
│
│
│
├0
┬─────────┬─────────┬────┘
0 10 20
x = 13.66 × col - -147.93 ± 6.83
y = 766.27 × row - -3438.73 ± 383.14
I also tried different configurations (no rows and cols, no equations, no color)
everytime it is the same... something is changed if you call show() again.
If the first data element in the list is 0, the Legend does not display the associated color.
>>> import plotext as plt
>>> dates = ['2022-01-01', '2022-01-02', '2022-01-03']
>>> dayc = [0, 1, 0]
>>> plt.bar(dates, dayc, label="Day")
>>> plt.plotsize(180, 40)
>>> plt.show()
Same for a stacked_bar:
import plotext as plt
dayc = [0, 1, 0]
nightc = [1, 0, 0]
dates = ['2022-01-01', '2022-01-02', '2022-01-03']
plt.stacked_bar(dates, [dayc, nightc], label=["Day", "Night"])
plt.plotsize(180, 40)
plt.show()
I tried to code up an example with streaming data but it flickers quite poorly. Am I doing something wrong?
import plotext.plot as plx
import numpy as np
pi = np.pi
x = np.linspace(0, 2*pi, 50)
y = np.sin(x)
t = np.linspace(0, 2, 50)
plx.clear_terminal()
plx.scatter(x,y,point_color="red", point_marker="o")
plx.set_cols(100)
plx.set_rows(100)
plx.set_ylim([-1.1,1.1])
plx.set_xlim([0,2*pi])
plx.set_axes_color("green")
plx.set_background("black")
plx.set_spacing([5,8])
plx.show()
for tt in t:
plx.clear_plot()
plx.clear_terminal()
y = np.sin(x-tt)
plx.scatter(x,y)
plx.show()
plx.sleep(0.1)
a quick test for continuous updates below.
i must remove the comment in the for loop to allow the plot to remain colorless, following the "Streaming Data" example.
plt.xlabel("Samples")
plt.ylabel("Value")
plt.xlim(0,256)
plt.colorless()
frameno = ctypes.c_int32()
for n in range(0,100):
sslib.GetSnapshot(0,0, ctypes.byref(frameno), char_array.from_buffer(plotData), len(plotData))
plotData = numpy.frombuffer(plotData, dtype=numpy.short)
plt.cld()
plt.clt()
plt.title(f"{frameno}")
plt.plot(plotData, marker="dot")
#plt.colorless()
plt.show()
Minimal example included
plt.bar(['a', 'b', 'c'], [1,1,1])
plt.show()
Traceback (most recent call last):
File "/home/coen/Documents/Macrohard/ProjectRatio/FramingSelection/venv/lib/python3.9/site-packages/IPython/core/interactiveshell.py", line 3457, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-13-1eb00ff78cf2>", line 1, in <module>
plt.show()
File "/home/coen/Documents/Macrohard/ProjectRatio/FramingSelection/venv/lib/python3.9/site-packages/plotext/_figure.py", line 281, in show
self.build()
File "/home/coen/Documents/Macrohard/ProjectRatio/FramingSelection/venv/lib/python3.9/site-packages/plotext/_figure.py", line 266, in build
self.subplot.get_absolute_ticks()
File "/home/coen/Documents/Macrohard/ProjectRatio/FramingSelection/venv/lib/python3.9/site-packages/plotext/_subplot.py", line 271, in get_absolute_ticks
self.rticks = [get_matrix_data(self.yticks[s], self.ylim[s], self.height_canvas) for s in range(2)]
File "/home/coen/Documents/Macrohard/ProjectRatio/FramingSelection/venv/lib/python3.9/site-packages/plotext/_subplot.py", line 271, in <listcomp>
self.rticks = [get_matrix_data(self.yticks[s], self.ylim[s], self.height_canvas) for s in range(2)]
File "/home/coen/Documents/Macrohard/ProjectRatio/FramingSelection/venv/lib/python3.9/site-packages/plotext/_utility/plot.py", line 30, in get_matrix_data
data = [round((el - lim[0]) / dz + 0.5, 1) for el in data]
File "/home/coen/Documents/Macrohard/ProjectRatio/FramingSelection/venv/lib/python3.9/site-packages/plotext/_utility/plot.py", line 30, in <listcomp>
data = [round((el - lim[0]) / dz + 0.5, 1) for el in data]
ZeroDivisionError: float division by zero
@piccolomo hey there. I am using your library in my project over at: https://github.com/cjmcgraw/docker-load-graph
Now there is clearly a problem on initial pip install. Specifically check out the following:
The first command shows my application throwing an exception for python3.8 at line 765.
The second command shows I am using version 3.1.3
of plotext (the most recent/current)
The third command, show sme catting the file that throwed the exception, and grepping around the lines.
Clearly there is a distinct typo returnsa
instead of return
there.
However in the current library I do not see that typo and thus don't have any immediate way of fixing this issue.
Could you please push the most recent changes you have in master to your release?
Thanks for really interesting library.
(IMHO) it could be more useful for to get the acsii-strings that is about to displayed without displaying on Terminal-Emulators.
So, with that strings, one can printout the plot over the Serial-Ports (i.e. pyserial),
For example I have a need for live updating plot over UART for some real time application.
Unicode version 13 introduced many glyphs used in older computers and terminals. Among those are the 2x3 mosaics used in Teletext terminals and the TRS-80 computers. Their use would represent a 50% increase of vertical resolution on terminals that support the character set.
Super cool package! Love the features. 😀
I was wondering if it was possible to add a way of creating histograms with this package. 📈
It would be super handy if the structure followed that of matplotlib just like your other functions does. 👨💻
Ability to add values to a secondary axis in the same plot.
plt.scatter(x, y1, y-axis=0)
plt.scatter(x, y2, y-axis=1)
I am wondering if there is a way to print some points with specific colors ( like if the points of (y) value are bigger than a defined number)
I'm getting the following error message.
Traceback (most recent call last):
File "plot.py", line 10, in <module>
plt.show()
File "/usr/local/lib/python3.9/dist-packages/plotext/plot.py", line 420, in show
_ylim_data(subplot)
File "/usr/local/lib/python3.9/dist-packages/plotext/plot.py", line 540, in _ylim_data
y_left = [_utility.log(subplot.y_left[s]) if subplot.yscale[0] == "log" else subplot.y_left[s] for s in range(subplot.signals_left)]
File "/usr/local/lib/python3.9/dist-packages/plotext/plot.py", line 540, in <listcomp>
y_left = [_utility.log(subplot.y_left[s]) if subplot.yscale[0] == "log" else subplot.y_left[s] for s in range(subplot.signals_left)]
File "/usr/local/lib/python3.9/dist-packages/plotext/utility.py", line 283, in log
return [math.log10(el) for el in data]
File "/usr/local/lib/python3.9/dist-packages/plotext/utility.py", line 283, in <listcomp>
return [math.log10(el) for el in data]
ValueError: math domain error
Here is my version of python and plotext.
Python 3.9.5 (default, May 11 2021, 08:20:37)
[GCC 10.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import plotext
>>> plotext.__version__
'3.1.3'
>>>
Here is the code to reproduce.
import plotext as plt
dates = ('2021-06-21', '2021-06-22', '2021-06-23', '2021-06-24', '2021-06-25', '2021-06-26')
counts = (2910, 3326, 19308, 126939, 475620, 226890)
plt.bar(dates, counts)
plt.plotsize(100, 30)
plt.yscale("log")
plt.show()
Googling suggests that math domain error
with a log means the value is 0 or negative. None of my original values are 0 or negative. But what's strange is that if I print out the value of data
in the plotext/utility.py:log(data)
function I get [2910, 2910, 0, 0]
. 2910
is my first y value, but I don't know what's going on with the rest.
Am I doing something wrong with how I'm using the library? Linear bar plots seem to work fine for me.
How to plot two lines in the same time?
If secondary axis is too difficult, would it be possible to have subplots, or multiple plots to display data?
Little bug I found here ... I am using Jupyterlab on Ubuntu 20.04 and I was getting the wide unicode block characters from a plot. I tried several different markers, (fhd, hd, dot, etc) and ended up with artifacts from previous markers on my plots. I eventually realized that this is because Jupyterlab is keeping the session open between the tests I was running and if I reset the python engine the artifact characters go away. Here is an example output having previously run the plot with fhd then hd:
Thanks for a great tool! :)
The code that determines the platform (in _utility.platform.py
) doesn't work for macOS, and it doesn't work for most flavors of Unix:
def platform(): # the platform (eg: linux) you are using plotext with
platform = sys.platform
names = ["win", "linux", "unix"]
platforms = ["windows", "linux", "unix"]
for i in range(3):
if names[i] in platform:
return platforms[i]
return "not found"
On macOS, platform
is "darwin"
, which contains "win"
and therefore gets labeled "windows".
I recommend rewriting that function to:
def platform(): # the platform (eg: linux) you are using plotext with
platform = sys.platform
# According to the docs, this returns one of: 'aix', 'linux', 'win32', 'cygwin',
# 'darwin', or the modified result of `uname -s` on other Unix systems.
if platform in {'win32', 'cygwin'}:
# These are the only two possible outputs on Windows systems
return 'windows'
else:
# Anything that is not Windows and that runs Python is a flavor of Unix
return 'unix'
Since you only ever check this value for Windows, I see no benefit in making a distinction between flavors of Unix. If you do want to make that distinction, why not just return the value of sys.platform
for Unix systems?
Similarly, your function _utility.platform.shell()
returns "cmd"
in any shell that is not Bash. On macOS, the new default is Zsh (which may people use on Linux too), and I'm sure there are people out there still using Csh and even Ksh. But it looks like this value is never actually used anywhere, so I guess it doesn't matter.
I won't submit a pull request, because this repository seems to have erased all its history. If you want people to contribute code, you should not do that.
Hello,
I have an error with this code:
x = list(np.arange(20, dtype=int))
y = list(np.full(20, 0, dtype=int))
plx.scatter(x, y, line=True, line_color='yellow', axes=True, ticks=True, equations=True)
plx.show()
File "/usr/local/lib/python3.6/dist-packages/plotext/plot.py", line 48, in show
_set_grid()
File "/usr/local/lib/python3.6/dist-packages/plotext/plot.py", line 322, in _set_grid
_add_to_grid(*_get_line(_vars.x[s], _vars.y[s]), _vars.line_marker[s], _vars.line_color[s])
File "/usr/local/lib/python3.6/dist-packages/plotext/plot.py", line 350, in _add_to_grid
r = int((y[n] - _vars.ymin) / _vars.dy)
ValueError: cannot convert float NaN to integer
But this code works fine:
x = list(np.arange(20, dtype=int))
y = list(np.full(20, 1, dtype=int))
plx.scatter(x, y, line=True, line_color='yellow', axes=True, ticks=True, equations=True)
plx.show()
First of all, thank you very much for the package!
I've found a little issue: if I try to use the dash package and plotext at the same time, I get import errors when I execute pytest. I think it is related to this problem with the dash plugin for pytest.
A straightforward solution is deleting this line from init.py: it's an import of the test
file that is not used later, but causes the problem with pytest.
In addition to that, maybe the name of the file test.py
should be changed so that it doesn't name-shadows a standard library name, which in this case is the internal package test.
Hi,
Using the latest version 2.2.2 with Streaming Data Example gives the following error:
AttributeError: 'function' object has no attribute 'scatter'
I can tell that the syntax has changed since.
What is the most optimised version to use this example?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.