Browse Source

Add trigonometric interpolation from redditor viscence

pull/35/merge
Florian Mounier 12 years ago
parent
commit
7b3279b71e
  1. 2
      demo/moulinrouge/tests.py
  2. 9
      pygal/graph/graph.py
  3. 32
      pygal/interpolate.py

2
demo/moulinrouge/tests.py

@ -174,7 +174,7 @@ def get_test_routes(app):
@app.route('/test/interpolate/<chart>')
def test_interpolate_for(chart):
graph = CHARTS_BY_NAME[chart](interpolate='hermite')
graph = CHARTS_BY_NAME[chart](interpolate='trigonometric')
graph.add('1', [1, 3, 12, 3, 4])
graph.add('2', [7, -4, 10, None, 8, 3, 1])
return graph.render_response()

9
pygal/graph/graph.py

@ -22,8 +22,7 @@ Commmon graphing functions
"""
from __future__ import division
from pygal.interpolate import (
quadratic_interpolate, cubic_interpolate, hermite_interpolate)
from pygal.interpolate import INTERPOLATIONS
from pygal.graph.base import BaseGraph
from pygal.view import View, LogView, XYLogView
from pygal.util import (
@ -415,11 +414,7 @@ class Graph(BaseGraph):
x.append(xs[i])
y.append(ys[i])
interpolate = cubic_interpolate
if self.interpolate == 'quadratic':
interpolate = quadratic_interpolate
elif self.interpolate == 'hermite':
interpolate = hermite_interpolate
interpolate = INTERPOLATIONS[self.interpolate]
return list(interpolate(x, y, self.interpolation_precision))

32
pygal/interpolate.py

@ -23,6 +23,7 @@ TODO: Implement more interpolations (cosine, lagrange...)
"""
from __future__ import division
from math import sin
def quadratic_interpolate(x, y, precision=250):
@ -124,6 +125,37 @@ def hermite_interpolate(x, y, precision=250):
X = x[i] + s * delta_x[i] / precision
yield X, p(i, X)
def trigonometric_interpolate(x, y, precision=250):
""" As per http://en.wikipedia.org/wiki/Trigonometric_interpolation"""
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
s = 0
for k in range(n + 1):
p = 1
for m in range(n + 1):
if m == k:
continue
p *= sin(0.5 * (X - x[m])) / sin(0.5 * (x[k] - x[m]))
s += y[k] * p
yield X, s
INTERPOLATIONS = {
'quadratic': quadratic_interpolate,
'cubic': cubic_interpolate,
'hermite': hermite_interpolate,
'trigonometric': trigonometric_interpolate
}
if __name__ == '__main__':
from pygal import XY
points = [(.1, 7), (.3, -4), (.6, 10), (.9, 8), (1.4, 3), (1.7, 1)]

Loading…
Cancel
Save