Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #118 from Freed-Wu/shtab
Browse files Browse the repository at this point in the history
Add bash/zsh/tcsh completion by shtab
piccolomo authored Aug 28, 2022
2 parents d3f1813 + 6d2ef47 commit a16d606
Showing 3 changed files with 132 additions and 104 deletions.
5 changes: 3 additions & 2 deletions plotext/__init__.py
Original file line number Diff line number Diff line change
@@ -3,8 +3,9 @@
__name__ = "plotext"
__version__ = "5.1.0"

from plotext._core import *
from plotext._test import test
from ._core import *
from ._test import test
from .plotext_cli import build_parser


def themes():
229 changes: 128 additions & 101 deletions plotext/plotext_cli.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,20 @@

import plotext as plt
import argparse, sys, os
import shtab
from plotext._utility import marker_codes, hd_symbols

colors_without_plus = ["black", "white"]
colors_with_plus = ["red", "green", "orange", "blue", "magenta", "cyan"]
colors = colors_without_plus + colors_with_plus
color_choices = colors + list(map(lambda s: s + "+", colors_with_plus))
markers = marker_codes.copy()
markers.update(hd_symbols)


def dict_to_complete(d={}):
return {'zsh': '((' + ' '.join(map(lambda x: str(x[0]) + '\\:' + x[1], d.items())) + '))'}


def build_parser():
examples = """Access each function documentation for further guidance, eg: plotext scatter -h"""
@@ -11,96 +25,105 @@ def build_parser():
description = "plotting directly on terminal",
epilog = examples,
formatter_class = argparse.RawDescriptionHelpFormatter)
shtab.add_argument_to(parser)

parser.set_defaults(type = "scatter")

path_parser = argparse.ArgumentParser(add_help = False)

path_parser.add_argument("-p", "--path",
action = 'store',
action = 'store',
#dest = 'path',
type = str,
help = "file path of the data table; if not used it will read from stdin. Use 'test' to automatically download, in your user folder, some test data/image/gif or video, depending on the function used; the file will be removed after the plot")
type = str,
metavar = "FILE",
help = "file path of the data table; if not used it will read from stdin. Use 'test' to automatically download, in your user folder, some test data/image/gif or video, depending on the function used; the file will be removed after the plot",
).complete = shtab.FILE

common_parser = argparse.ArgumentParser(add_help = False)

common_parser.add_argument("-clt", "--clear_terminal",
nargs = 1,
type = str,
default = ["False"],
choices = ["True", "False"],
help = "it clears the terminal before plotting, if True (as by default)")
nargs = 1,
type = str,
default = ["False"],
choices = ["True", "False"],
metavar = "BOOL",
help = "it clears the terminal before plotting, if True (as by default)")

common_parser.add_argument("-s", "--sleep",
nargs = 1,
type = float,
default = [0],
help = "it adds a sleeping time after plotting, to reduce flickering when multiple plots are required; 0 by default")
nargs = 1,
type = float,
default = [0],
help = "it adds a sleeping time after plotting, to reduce flickering when multiple plots are required; 0 by default")

data_parser = argparse.ArgumentParser(add_help = False)

data_parser.add_argument("-xcol", "--xcolumn",
nargs = "+", # 1 or more
type = str,
default = ["none"],
help = "the column number (starting from 1), in the data table, that will be used as x data; by default 'none'")
nargs = "+", # 1 or more
type = str,
default = ["none"],
help = "the column number (starting from 1), in the data table, that will be used as x data; by default 'none'")

data_parser.add_argument("-ycols", "--ycolumns",
nargs = "+", # 1 or more
type = str,
default = ["all"],
help = "the column numbers (starting from 1), in the data table, that will be used as y data; by default 'all'")
nargs = "+", # 1 or more
type = str,
default = ["all"],
help = "the column numbers (starting from 1), in the data table, that will be used as y data; by default 'all'")

data_parser.add_argument("-d", "--delimiter",
type = str,
default = [' '],
nargs = 1,
help = "character to be used to separate columns in the data table (eg: ;); by default the white space ' '")
type = str,
default = [' '],
nargs = 1,
help = "character to be used to separate columns in the data table (eg: ;); by default the white space ' '")

data_parser.add_argument("-l", "--lines",
nargs = "+", # 1 or more
type = int,
default = [1000],
help = "number of lines, from data table, to be plotted at each iteration; 1000 by default; data shorter then this will be plotted in a single iteration")
nargs = "+", # 1 or more
type = int,
default = [1000],
help = "number of lines, from data table, to be plotted at each iteration; 1000 by default; data shorter then this will be plotted in a single iteration")

options_parser = argparse.ArgumentParser(add_help = False)

options_parser.add_argument("-m", "--marker",
type = str,
default = ['hd'],
nargs = 1,
help = "character or marker code identifying the data points in the plot, eg: x, braille, sd, heart, fhd; by default hd")

type = str,
default = ['hd'],
nargs = 1,
choices = list(hd_symbols.keys())[::-1] + list(marker_codes.keys()),
metavar = "marker",
help = "character or marker code identifying the data points in the plot, eg: x, braille, sd, heart, fhd; by default hd",
).complete = dict_to_complete(markers)
options_parser.add_argument("-c", "--color",
type = str,
default = [None],
nargs = 1,
help = "color of the data points in the plot, between: black, white, red, green, orange, blue, magenta, cyan; add + at the end of the color (except black and white) for clearer colors, eg: red+")
type = str,
default = [None],
nargs = 1,
choices = color_choices,
metavar = "COLOR",
help = "color of the data points in the plot, between: " + ",".join(colors) + "; add + at the end of the color (except black and white) for clearer colors, eg: red+")

options_parser.add_argument("-t", "--title",
nargs = 1,
type = str,
default = [None],
help = "the plot title")
nargs = 1,
type = str,
default = [None],
help = "the plot title")

options_parser.add_argument("-xl", "--xlabel",
nargs = 1,
type = str,
default = [None],
help = "the label of the x axis")
nargs = 1,
type = str,
default = [None],
help = "the label of the x axis")

options_parser.add_argument("-yl", "--ylabel",
nargs = 1,
type = str,
default = [None],
help = "the label of the y axis")
nargs = 1,
type = str,
default = [None],
help = "the label of the y axis")

options_parser.add_argument("-g", "--grid",
nargs = 1,
type = str,
default = ["False"],
choices = ["True", "False"],
help = "it add grid lines if True, or removed them if False (as by default)")
nargs = 1,
type = str,
default = ["False"],
choices = ["True", "False"],
metavar = "BOOL",
help = "it add grid lines if True, or removed them if False (as by default)")

barhist_parser = argparse.ArgumentParser(add_help = False)

@@ -109,13 +132,15 @@ def build_parser():
type = str,
default = ['v'],
choices = ['v', 'h'],
metavar = "ORIENTATION",
help = "bar orientation, v for vertical (as by default), h for horizontal")

barhist_parser.add_argument("-f", "--fill",
nargs = 1,
type = str,
default = ["True"],
choices = ["True", "False"],
metavar = "BOOL",
help = "it fills the bars with colored markers if True (as by default), otherwise only the bars skeleton is shown")

subparser = parser.add_subparsers(dest = 'type',
@@ -136,71 +161,73 @@ def build_parser():

plotter = subparser.add_parser('plotter',
parents = [path_parser, data_parser, common_parser, options_parser],
description = 'plots a series of data points and the lines between consecutive ones',
description = 'plots a series of data points and the lines between consecutive ones',
help = 'scatter + plot',
epilog = "eg:plotext plotter --path test --xcolumn 1 --ycolumns 2 --sleep 0.1 --lines 120 --clear_terminal True --marker hd --title 'Plotter Test'")

bar = subparser.add_parser('bar',
parents = [path_parser, data_parser, common_parser, options_parser, barhist_parser],
description = 'builds a bar plot',
help = 'bar plot',
epilog = "eg: plotext bar --path test --xcolumn 1 --title 'Bar Plot Test' --xlabel Animals --ylabel Count")

bar.add_argument("-w", "--width",
nargs = 1,
type = float,
default = [None],
help = "bars width as a float between 0 and 1")
nargs = 1,
type = float,
default = [None],
help = "bars width as a float between 0 and 1")

hist = subparser.add_parser('hist',
parents = [path_parser, data_parser, common_parser, options_parser, barhist_parser],
parents = [path_parser, data_parser, common_parser, options_parser, barhist_parser],
description = 'builds a histogram plot',
help = 'histogram plot',
epilog = "eg: plotext hist --path test --xcolumn 1 --ycolumns 2 --lines 5000 --title 'Histogram Test'")
help = 'histogram plot',
epilog = "eg: plotext hist --path test --xcolumn 1 --ycolumns 2 --lines 5000 --title 'Histogram Test'")

hist.add_argument("-b", "--bins",
nargs = 1,
type = int,
default = [10],
help = "histogram bins (10 by default)")
nargs = 1,
type = int,
default = [10],
help = "histogram bins (10 by default)")

image = subparser.add_parser('image',
parents = [path_parser, common_parser],
parents = [path_parser, common_parser],
description = 'plots an image from path',
help = 'plots an image from file path',
epilog = "eg: plotext image --path test")
help = 'plots an image from file path',
epilog = "eg: plotext image --path test")

gif = subparser.add_parser('gif',
parents = [path_parser, common_parser],
parents = [path_parser, common_parser],
description = 'plays a gif image from path',
help = 'plays a gif image from path',
epilog = "eg: plotext gif --path test")
help = 'plays a gif image from path',
epilog = "eg: plotext gif --path test")

video = subparser.add_parser('video',
parents = [path_parser, common_parser],
parents = [path_parser, common_parser],
description = 'plays a video from path',
help = 'plays a video from path',
epilog = "eg: plotext video --path test --from_youtube True")
help = 'plays a video from path',
epilog = "eg: plotext video --path test --from_youtube True")

video.add_argument("-fy", "--from_youtube",
nargs = 1,
type = str,
default = ["False"],
choices = ["True", "False"],
help = "set it to True to render the colors correctly for videos downloaded from youtube; default is False")
nargs = 1,
type = str,
default = ["False"],
choices = ["True", "False"],
metavar = "BOOL",
help = "set it to True to render the colors correctly for videos downloaded from youtube; default is False")

youtube = subparser.add_parser('youtube',
description = 'plays a youtube video from url',
help = 'plays a youtube video from url',
epilog = "eg: plotext youtube --url test")

youtube.add_argument("-u", "--url",
action = 'store',
dest = 'url',
nargs = 1,
type = str,
help = "the url of a youtube video; use 'test' for a test video")

action = 'store',
dest = 'url',
nargs = 1,
type = str,
metavar = "URL",
help = "the url of a youtube video; use 'test' for a test video")

return parser


@@ -239,10 +266,10 @@ def plot(x, Y):
plt.show()
plt.cld()
plt.sleep(sleep)

data_plot = ['scatter', 'plot', 'plotter', 'bar', 'hist']
test_path = 'test'

if type in data_plot:
lines = args.lines[0]
delimiter = args.delimiter[0]
@@ -255,30 +282,30 @@ def plot(x, Y):
fill = args.fill[0] == 'True' if type in ['bar', 'hist'] else False
width = args.width[0] if type == 'bar' else 0
bins = args.bins[0] if type in 'hist' else None

marker = args.marker[0]
color = args.color[0]

plt.title(title);
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.grid(grid)

if path == test_path:
plt.plotsize(None, plt.th() - 2)
if type != "bar":
plt.download(plt.test_data_url, test_path, log = False)
else:
plt.download(plt.test_bar_data_url, test_path, log = False)
path = test_path

if path is None:
def plot_text(text):
data = plt._utility.read_lines(text, delimiter = delimiter)
data = plt.transpose(data)
x, Y = get_xY(data)
plot(x, Y)

text = []
i = 0
for line in iter(sys.stdin.readline, ''):
@@ -316,15 +343,15 @@ def plot_text(text):
plt.download(plt.test_gif_url, test_path, log = False)
path = test_path
plt.play_gif(path)

elif type == 'video':
if path == test_path:
plt.plotsize(None, plt.th() - 1)
plt.download(plt.test_video_url, test_path, log = False)
path = test_path
from_youtube = True if args.from_youtube[-1] == 'True' else False
plt.play_video(path, from_youtube)

elif type == 'youtube':
url = args.url[-1]
url = plt.test_youtube_url if url == test_path else url
@@ -333,6 +360,6 @@ def plot_text(text):
if os.path.isfile(test_path):
plt.delete_file(test_path, True)


if __name__ == "__main__":
sys.exit(main())
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
packages = find_packages(),
python_requires = ">=3.5",
include_package_data = True,
install_requires = [],
install_requires = ["shtab"],
extras_require = {"image": ["pillow>=8.4"], "video": ["pillow>=8.4", "pafy>=0.5.5", "opencv-python>=4.5.5", "ffpyplayer>=4.3.5", "youtube-dl==2020.12.2"]},
classifiers = []
)

0 comments on commit a16d606

Please sign in to comment.