From b6128aa917ccbff986c679fd93dbd48639b34cda Mon Sep 17 00:00:00 2001 From: Hendrik Schawe Date: Fri, 8 Jun 2018 10:55:39 +0200 Subject: [PATCH 1/2] added a constant interpolation, i.e., a step function --- .../configuration/interpolations.rst | 9 +++++++++ pygal/interpolate.py | 17 ++++++++++++++++- pygal/test/test_interpolate.py | 7 +++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/documentation/configuration/interpolations.rst b/docs/documentation/configuration/interpolations.rst index b232cae0..648d8e0c 100644 --- a/docs/documentation/configuration/interpolations.rst +++ b/docs/documentation/configuration/interpolations.rst @@ -50,6 +50,15 @@ trigonometric chart.add('line', [1, 5, 17, 12, 5, 10]) +constant +~~~~~~~~ + +.. pygal-code:: + + chart = pygal.Line(interpolate='constant') + chart.add('line', [1, 5, 17, 12, 5, 10]) + + hermite ~~~~~~~ diff --git a/pygal/interpolate.py b/pygal/interpolate.py index 58bc39a5..37b57cc9 100644 --- a/pygal/interpolate.py +++ b/pygal/interpolate.py @@ -230,12 +230,26 @@ def trigonometric_interpolate(x, y, precision=250, **kwargs): yield X, s +def constant_interpolate(x, y, precision=250, **kwargs): + n = len(x) - 1 + delta_x = [x2 - x1 for x1, x2 in zip(x, x[1:])] + for i in range(n + 1): + yield x[i], y[i] + if i == n or delta_x[i] == 0: + continue + + for s in range(1, precision): + X = x[i] + s * delta_x[i] / precision + yield X, y[i] + + INTERPOLATIONS = { 'quadratic': quadratic_interpolate, 'cubic': cubic_interpolate, 'hermite': hermite_interpolate, 'lagrange': lagrange_interpolate, - 'trigonometric': trigonometric_interpolate + 'trigonometric': trigonometric_interpolate, + 'constant': constant_interpolate } if __name__ == '__main__': @@ -247,6 +261,7 @@ def trigonometric_interpolate(x, y, precision=250, **kwargs): xy.add('cubic', cubic_interpolate(*zip(*points))) xy.add('lagrange', lagrange_interpolate(*zip(*points))) xy.add('trigonometric', trigonometric_interpolate(*zip(*points))) + xy.add('constant', constant_interpolate(*zip(*points))) xy.add( 'hermite catmul_rom', hermite_interpolate(*zip(*points), type='catmul_rom') diff --git a/pygal/test/test_interpolate.py b/pygal/test/test_interpolate.py index eb7bdc27..332e2f22 100644 --- a/pygal/test/test_interpolate.py +++ b/pygal/test/test_interpolate.py @@ -60,6 +60,13 @@ def test_trigonometric(Chart, datas): assert chart.render() +def test_constant(Chart, datas): + """Test constant interpolation""" + chart = Chart(interpolate='constant') + chart = make_data(chart, datas) + assert chart.render() + + def test_hermite(Chart, datas): """Test hermite interpolation""" chart = Chart(interpolate='hermite') From 34479fa8c85f0082fa84ebafec85022aff9542f3 Mon Sep 17 00:00:00 2001 From: Hendrik Schawe Date: Fri, 8 Jun 2018 12:09:08 +0200 Subject: [PATCH 2/2] Do not use unecessarily many datapoints The precision argument is not applicable to constant interpolation, since it consists of straight lines. --- pygal/interpolate.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pygal/interpolate.py b/pygal/interpolate.py index 37b57cc9..eddcacfc 100644 --- a/pygal/interpolate.py +++ b/pygal/interpolate.py @@ -230,7 +230,7 @@ def trigonometric_interpolate(x, y, precision=250, **kwargs): yield X, s -def constant_interpolate(x, y, precision=250, **kwargs): +def constant_interpolate(x, y, **kwargs): n = len(x) - 1 delta_x = [x2 - x1 for x1, x2 in zip(x, x[1:])] for i in range(n + 1): @@ -238,9 +238,8 @@ def constant_interpolate(x, y, precision=250, **kwargs): if i == n or delta_x[i] == 0: continue - for s in range(1, precision): - X = x[i] + s * delta_x[i] / precision - yield X, y[i] + X = x[i] + delta_x[i] + yield X, y[i] INTERPOLATIONS = {