Skip to content

Commit

Permalink
Hist single value (#34)
Browse files Browse the repository at this point in the history
* hist: On equal values,  add/substract 0.5 for min/max
* Fix similar issue for plot  / scatter
* v3.7.1
* Update tested versions
* flake8
  • Loading branch information
tammoippen authored Aug 31, 2020
1 parent 41f50df commit 2fc3d58
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 66 deletions.
25 changes: 18 additions & 7 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,19 @@ jobs:
test_2_7:
executor:
name: python
image: "circleci/python:2.7.15"
image: "circleci/python:2.7"
steps:
- tester
test_2_7_pypy:
executor:
name: python
image: "pypy:2-7.1.0"
image: "pypy:2.7-7.3"
steps:
- tester
test_3_5:
executor:
name: python
image: "circleci/python:3.5.6"
image: "circleci/python:3.5"
steps:
- tester
test_3_5_pypy:
Expand All @@ -105,25 +105,31 @@ jobs:
test_3_6:
executor:
name: python
image: "circleci/python:3.6.7"
image: "circleci/python:3.6"
steps:
- tester
test_3_6_pypy:
executor:
name: python
image: "pypy:3.6-7.1.0"
image: "pypy:3.6-7.3"
steps:
- tester
test_3_7:
executor:
name: python
image: "circleci/python:3.7.1"
image: "circleci/python:3.7"
steps:
- tester
test_3_8:
executor:
name: python
image: "circleci/python:3.8"
steps:
- tester

deploy_job:
docker:
- image: circleci/python:3.6.7
- image: circleci/python:3.6
description: "Deploy plotille to pypi."
steps:
- checkout
Expand Down Expand Up @@ -173,6 +179,10 @@ workflows:
filters:
tags:
only: /.*/
- test_3_8:
filters:
tags:
only: /.*/
- deploy_job:
requires:
- test_2_7
Expand All @@ -182,6 +192,7 @@ workflows:
- test_3_6
- test_3_6_pypy
- test_3_7
- test_3_8
filters:
branches:
ignore: /.*/
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
[![CircleCI](https://circleci.com/gh/tammoippen/plotille.svg?style=svg)](https://circleci.com/gh/tammoippen/plotille)
[![Coverage Status](https://coveralls.io/repos/github/tammoippen/plotille/badge.svg?branch=master)](https://coveralls.io/github/tammoippen/plotille?branch=master)
[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/tammoippen/plotille.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/tammoippen/plotille/context:python)
[![Tested CPython Versions](https://img.shields.io/badge/cpython-2.7%2C%203.5%2C%203.6%2C%203.7-brightgreen.svg)](https://img.shields.io/badge/cpython-2.7%2C%203.5%2C%203.6%2C%203.7-brightgreen.svg)
[![Tested PyPy Versions](https://img.shields.io/badge/pypy-2.7--7.1.0%2C%203.5--7.0.0%2C%203.6--7.1.0-brightgreen.svg)](https://img.shields.io/badge/pypy-2.7--6.0.0%2C%203.5--6.0.0-brightgreen.svg)
[![Tested CPython Versions](https://img.shields.io/badge/cpython-2.7%2C%203.5%2C%203.6%2C%203.7%2C%203.8-brightgreen.svg)](https://img.shields.io/badge/cpython-2.7%2C%203.5%2C%203.6%2C%203.7%2C%203.8-brightgreen.svg)
[![Tested PyPy Versions](https://img.shields.io/badge/pypy-2.7--7.3%2C%203.5--7.0.0%2C%203.6--7.3-brightgreen.svg)](https://img.shields.io/badge/pypy-2.7--7.3%2C%203.5--7.0.0%2C%203.6--7.3-brightgreen.svg)
[![PyPi version](https://img.shields.io/pypi/v/plotille.svg)](https://pypi.python.org/pypi/plotille)
[![PyPi license](https://img.shields.io/pypi/l/plotille.svg)](https://pypi.python.org/pypi/plotille)

Expand Down
2 changes: 1 addition & 1 deletion plotille/_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def _hex2rgb(h):
if h.lower().startswith('0x'):
h = h[2:]
if len(h) == 3:
return (int(h[0]*2, base=16), int(h[1]*2, base=16), int(h[2]*2, base=16))
return (int(h[0] * 2, base=16), int(h[1] * 2, base=16), int(h[2] * 2, base=16))
if len(h) == 6:
return (int(h[0:2], base=16), int(h[2:4], base=16), int(h[4:6], base=16))

Expand Down
30 changes: 16 additions & 14 deletions plotille/_figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,19 +238,19 @@ def _x_axis(self, xmin, xmax, label='X', with_y_axis=False):
def clear(self):
self._plots = []

def plot(self, X, Y, lc=None, interp='linear', label=None): # noqa: N803
def plot(self, X, Y, lc=None, interp='linear', label=None):
if len(X) > 0:
if lc is None:
lc = next(self._color_seq)[self.color_mode]
self._plots += [Plot.create(X, Y, lc, interp, label)]

def scatter(self, X, Y, lc=None, label=None): # noqa: N803
def scatter(self, X, Y, lc=None, label=None):
if len(X) > 0:
if lc is None:
lc = next(self._color_seq)[self.color_mode]
self._plots += [Plot.create(X, Y, lc, None, label)]

def histogram(self, X, bins=160, lc=None): # noqa: N803
def histogram(self, X, bins=160, lc=None):
if len(X) > 0:
if lc is None:
lc = next(self._color_seq)[self.color_mode]
Expand Down Expand Up @@ -283,16 +283,16 @@ def show(self, legend=False):
# add y axis
yaxis = self._y_axis(ymin, ymax, label=self.y_label)
res = (
yaxis[0] + self.linesep + # up arrow
yaxis[1] + self.linesep + # maximum
self.linesep.join(lbl + line for lbl, line in zip(yaxis[2:], res.split(self.linesep)))
yaxis[0] + self.linesep # up arrow
+ yaxis[1] + self.linesep # maximum
+ self.linesep.join(lbl + line for lbl, line in zip(yaxis[2:], res.split(self.linesep)))
)

# add x axis
xaxis = self._x_axis(xmin, xmax, label=self.x_label, with_y_axis=True)
res = (
res + self.linesep + # plot
self.linesep.join(xaxis)
res + self.linesep # plot
+ self.linesep.join(xaxis)
)

if legend:
Expand All @@ -309,7 +309,7 @@ def show(self, legend=False):
class Plot(namedtuple('Plot', ['X', 'Y', 'lc', 'interp', 'label'])):

@classmethod
def create(cls, X, Y, lc, interp, label): # noqa: N803
def create(cls, X, Y, lc, interp, label):
if len(X) != len(Y):
raise ValueError('X and Y dim have to be the same.')
if interp not in ('linear', None):
Expand All @@ -329,21 +329,23 @@ def write(self, canvas, with_colors, in_fmt):
to_points = zip(map(in_fmt.convert, self.X), map(in_fmt.convert, self.Y))

# remove first point of to_points
next(to_points)
(x0, y0) = next(to_points)

color = self.lc if with_colors else None
# plot points
for (x0, y0), (x, y) in zip(from_points, to_points):
canvas.point(x0, y0, color=color)

# print first point
canvas.point(x0, y0, color=color)

# plot other points and lines
for (x0, y0), (x, y) in zip(from_points, to_points):
canvas.point(x, y, color=color)
if self.interp == 'linear':
canvas.line(x0, y0, x, y, color=color)


class Histogram(namedtuple('Histogram', ['X', 'bins', 'frequencies', 'buckets', 'lc'])):
@classmethod
def create(cls, X, bins, lc): # noqa: N803
def create(cls, X, bins, lc):
frequencies, buckets = hist(X, bins)

return cls(X, bins, frequencies, buckets, lc)
Expand Down
14 changes: 7 additions & 7 deletions plotille/_graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from ._util import hist as compute_hist


def hist(X, bins=40, width=80, log_scale=False, linesep=os.linesep, # noqa: N803
def hist(X, bins=40, width=80, log_scale=False, linesep=os.linesep,
lc=None, bg=None, color_mode='names'):
"""Create histogram over `X` from left to right
Expand Down Expand Up @@ -70,14 +70,14 @@ def _scale(a):
canvas += ['[{}, {}) | {} {}'.format(
ipf.fmt(b[i], delta=delta, chars=8, left=True),
ipf.fmt(b[i + 1], delta=delta, chars=8, left=False),
color('⣿' * (hight // 8) + lasts[hight % 8], fg=lc, bg=bg, mode=color_mode) +
color('\u2800' * (width - (hight // 8) + int(hight % 8 == 0)), bg=bg, mode=color_mode),
color('⣿' * (hight // 8) + lasts[hight % 8], fg=lc, bg=bg, mode=color_mode)
+ color('\u2800' * (width - (hight // 8) + int(hight % 8 == 0)), bg=bg, mode=color_mode),
h[i])]
canvas += ['‾' * (2*8 + 2 + 3 + width + 12)]
canvas += ['‾' * (2 * 8 + 2 + 3 + width + 12)]
return linesep.join(canvas)


def histogram(X, bins=160, width=80, height=40, X_label='X', Y_label='Counts', linesep=os.linesep, # noqa: N803
def histogram(X, bins=160, width=80, height=40, X_label='X', Y_label='Counts', linesep=os.linesep,
x_min=None, x_max=None, y_min=None, y_max=None,
lc=None, bg=None, color_mode='names'):
"""Create histogram over `X`
Expand Down Expand Up @@ -128,7 +128,7 @@ def histogram(X, bins=160, width=80, height=40, X_label='X', Y_label='Counts', l
return fig.show()


def scatter(X, Y, width=80, height=40, X_label='X', Y_label='Y', linesep=os.linesep, # noqa: N803
def scatter(X, Y, width=80, height=40, X_label='X', Y_label='Y', linesep=os.linesep,
x_min=None, x_max=None, y_min=None, y_max=None,
lc=None, bg=None, color_mode='names', origin=True):
"""Create scatter plot with X , Y values
Expand Down Expand Up @@ -159,7 +159,7 @@ def scatter(X, Y, width=80, height=40, X_label='X', Y_label='Y', linesep=os.line
x_min, x_max, y_min, y_max, lc, bg, color_mode, origin)


def plot(X, Y, width=80, height=40, X_label='X', Y_label='Y', linesep=os.linesep, interp='linear', # noqa: N803
def plot(X, Y, width=80, height=40, X_label='X', Y_label='Y', linesep=os.linesep, interp='linear',
x_min=None, x_max=None, y_min=None, y_max=None,
lc=None, bg=None, color_mode='names', origin=True):
"""Create plot with X , Y values and linear interpolation between points
Expand Down
5 changes: 4 additions & 1 deletion plotille/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def roundeven(x):
return x_r


def hist(X, bins): # noqa: N803
def hist(X, bins):
"""Create histogram similar to `numpy.hist()`
Parameters:
Expand All @@ -66,6 +66,9 @@ def hist(X, bins): # noqa: N803

xmin = min(X) if len(X) > 0 else 0.0
xmax = max(X) if len(X) > 0 else 1.0
if xmin == xmax:
xmin -= 0.5
xmax += 0.5
delta = xmax - xmin
is_datetime = False
if isinstance(delta, timedelta):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]

name = "plotille"
version = "3.7"
version = "3.7.1"
description = "Plot in the terminal using braille dots."
authors = ["Tammo Ippen <[email protected]>"]
license = "MIT"
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ branch = True
application_import_names = plotille
max-line-length = 120
import-order-style = google
ignore = N803 W503

[tool:pytest]
python_paths = .
Expand Down
16 changes: 8 additions & 8 deletions tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,22 @@ def test_rgb(tty):

fgh = hex(fg)[2:].rjust(2, str('0'))
assert '\x1b[38;2;{};{};{}m \x1b[0m'.format(fg, fg, fg) == clr.color(' ', fgh + fgh + fgh, None, mode='rgb')
assert ('\x1b[38;2;{};{};{}m \x1b[0m'.format(fg, fg, fg) ==
clr.color(' ', '0x' + fgh + fgh + fgh, None, mode='rgb'))
assert ('\x1b[38;2;{};{};{}m \x1b[0m'.format(fg, fg, fg)
== clr.color(' ', '0x' + fgh + fgh + fgh, None, mode='rgb'))

for bg in range(0, 256):
assert '\x1b[48;2;{};{};{}m'.format(bg, bg, bg) == clr._rgb(None, (bg, bg, bg))
assert '\x1b[48;2;{};{};{}m \x1b[0m'.format(bg, bg, bg) == clr.color(' ', None, (bg, bg, bg), mode='rgb')

bgh = hex(bg)[2:].rjust(2, str('0'))
assert '\x1b[48;2;{};{};{}m \x1b[0m'.format(bg, bg, bg) == clr.color(' ', None, bgh + bgh + bgh, mode='rgb')
assert ('\x1b[48;2;{};{};{}m \x1b[0m'.format(bg, bg, bg) ==
clr.color(' ', None, '0x' + bgh + bgh + bgh, mode='rgb'))
assert ('\x1b[48;2;{};{};{}m \x1b[0m'.format(bg, bg, bg)
== clr.color(' ', None, '0x' + bgh + bgh + bgh, mode='rgb'))

assert ('\x1b[38;2;{};{};{};48;2;{};{};{}m'.format(fg, fg, fg, bg, bg, bg) ==
clr._rgb((fg, fg, fg), (bg, bg, bg)))
assert ('\x1b[38;2;{};{};{};48;2;{};{};{}m \x1b[0m'.format(fg, fg, fg, bg, bg, bg) ==
clr.color(' ', (fg, fg, fg), (bg, bg, bg), mode='rgb'))
assert ('\x1b[38;2;{};{};{};48;2;{};{};{}m'.format(fg, fg, fg, bg, bg, bg)
== clr._rgb((fg, fg, fg), (bg, bg, bg)))
assert ('\x1b[38;2;{};{};{};48;2;{};{};{}m \x1b[0m'.format(fg, fg, fg, bg, bg, bg)
== clr.color(' ', (fg, fg, fg), (bg, bg, bg), mode='rgb'))

with pytest.raises(ValueError):
clr._rgb(-15, None)
Expand Down
20 changes: 10 additions & 10 deletions tests/test_date_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@ def day():


def test_days(date_a, day):
assert ' 19-01-02' == _date_formatter(date_a, chars=9, delta=day*15)
assert '19-01-02 ' == _date_formatter(date_a, chars=9, delta=day*15, left=True)
assert ' 19-01-02' == _date_formatter(date_a, chars=9, delta=day * 15)
assert '19-01-02 ' == _date_formatter(date_a, chars=9, delta=day * 15, left=True)

assert ' 2019-01-02' == _date_formatter(date_a, chars=12, delta=day*15)
assert '2019-01-02 ' == _date_formatter(date_a, chars=12, delta=day*15, left=True)
assert ' 2019-01-02' == _date_formatter(date_a, chars=12, delta=day * 15)
assert '2019-01-02 ' == _date_formatter(date_a, chars=12, delta=day * 15, left=True)

with pytest.raises(ValueError):
_date_formatter(date_a, chars=7, delta=day*15)
_date_formatter(date_a, chars=7, delta=day * 15)


def test_day_times(date_a, day):
assert ' 02T00:00' == _date_formatter(date_a, chars=9, delta=day*5)
assert '02T00:00 ' == _date_formatter(date_a, chars=9, delta=day*5, left=True)
assert ' 02T00:00' == _date_formatter(date_a, chars=9, delta=day * 5)
assert '02T00:00 ' == _date_formatter(date_a, chars=9, delta=day * 5, left=True)

assert ' 02T00:00:00' == _date_formatter(date_a, chars=12, delta=day*5)
assert '02T00:00:00 ' == _date_formatter(date_a, chars=12, delta=day*5, left=True)
assert ' 02T00:00:00' == _date_formatter(date_a, chars=12, delta=day * 5)
assert '02T00:00:00 ' == _date_formatter(date_a, chars=12, delta=day * 5, left=True)

with pytest.raises(ValueError):
_date_formatter(date_a, chars=7, delta=day*5)
_date_formatter(date_a, chars=7, delta=day * 5)


def test_converter(date_a):
Expand Down
30 changes: 15 additions & 15 deletions tests/test_datetime_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,36 @@ def hour():


def test_days(date, day):
assert ' 18-01-21' == _datetime_formatter(date, chars=9, delta=day*15)
assert '18-01-21 ' == _datetime_formatter(date, chars=9, delta=day*15, left=True)
assert ' 18-01-21' == _datetime_formatter(date, chars=9, delta=day * 15)
assert '18-01-21 ' == _datetime_formatter(date, chars=9, delta=day * 15, left=True)

assert ' 2018-01-21' == _datetime_formatter(date, chars=12, delta=day*15)
assert '2018-01-21 ' == _datetime_formatter(date, chars=12, delta=day*15, left=True)
assert ' 2018-01-21' == _datetime_formatter(date, chars=12, delta=day * 15)
assert '2018-01-21 ' == _datetime_formatter(date, chars=12, delta=day * 15, left=True)

with pytest.raises(ValueError):
_datetime_formatter(date, chars=7, delta=day*15)
_datetime_formatter(date, chars=7, delta=day * 15)


def test_day_times(date, day):
assert ' 21T15:03' == _datetime_formatter(date, chars=9, delta=day*5)
assert '21T15:03 ' == _datetime_formatter(date, chars=9, delta=day*5, left=True)
assert ' 21T15:03' == _datetime_formatter(date, chars=9, delta=day * 5)
assert '21T15:03 ' == _datetime_formatter(date, chars=9, delta=day * 5, left=True)

assert ' 21T15:03:12' == _datetime_formatter(date, chars=12, delta=day*5)
assert '21T15:03:12 ' == _datetime_formatter(date, chars=12, delta=day*5, left=True)
assert ' 21T15:03:12' == _datetime_formatter(date, chars=12, delta=day * 5)
assert '21T15:03:12 ' == _datetime_formatter(date, chars=12, delta=day * 5, left=True)

with pytest.raises(ValueError):
_datetime_formatter(date, chars=7, delta=day*5)
_datetime_formatter(date, chars=7, delta=day * 5)


def test_times(date, hour):
assert ' 15:03:12' == _datetime_formatter(date, chars=9, delta=hour*5)
assert '15:03:12 ' == _datetime_formatter(date, chars=9, delta=hour*5, left=True)
assert ' 15:03:12' == _datetime_formatter(date, chars=9, delta=hour * 5)
assert '15:03:12 ' == _datetime_formatter(date, chars=9, delta=hour * 5, left=True)

assert ' 15:03:12.001234' == _datetime_formatter(date, chars=16, delta=hour*5)
assert '15:03:12.001234 ' == _datetime_formatter(date, chars=16, delta=hour*5, left=True)
assert ' 15:03:12.001234' == _datetime_formatter(date, chars=16, delta=hour * 5)
assert '15:03:12.001234 ' == _datetime_formatter(date, chars=16, delta=hour * 5, left=True)

with pytest.raises(ValueError):
_datetime_formatter(date, chars=7, delta=hour*5)
_datetime_formatter(date, chars=7, delta=hour * 5)


def test_converter(date):
Expand Down
Loading

0 comments on commit 2fc3d58

Please sign in to comment.