Skip to content

Commit

Permalink
Document interpolation and add a larger stroke width on active
Browse files Browse the repository at this point in the history
  • Loading branch information
paradoxxxzero committed Jul 13, 2015
1 parent 8805b3d commit 09480b5
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 12 deletions.
13 changes: 10 additions & 3 deletions demo/moulinrouge/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ def index():

@app.route("/svg/<type>/<series>/<config>")
def svg(type, series, config):
graph = getattr(pygal, type)(pickle.loads(b64decode(str(config))))
module = '.'.join(type.split('.')[:-1])
name = type.split('.')[-1]
from importlib import import_module
graph = getattr(import_module(module), name)(
pickle.loads(b64decode(str(config))))
for title, values in pickle.loads(b64decode(str(series))):
graph.add(title, values)
return graph.render_response()
Expand Down Expand Up @@ -196,10 +200,13 @@ def all(style='default', color=None, interpolate=None, base_style=None):
config.human_readable = True
config.interpolate = interpolate
config.style = style
config.x_labels = [random_label() for i in range(data)]
svgs = []
for chart in pygal.CHARTS:
type = chart.__name__
type = '.'.join((chart.__module__, chart.__name__))
if chart._dual:
config.x_labels = None
else:
config.x_labels = [random_label() for i in range(data)]
svgs.append({'type': type,
'series': xy_series if type == 'XY' else other_series,
'config': b64encode(pickle.dumps(config))})
Expand Down
4 changes: 4 additions & 0 deletions pygal/_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Various hacks for transparent python 2 / python 3 support
"""

import sys
from collections import Iterable
import time
Expand Down
8 changes: 7 additions & 1 deletion pygal/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@


def positive(x):
"""Return zero if value is negative"""
if x is None:
return
if x < 0:
Expand All @@ -32,16 +33,21 @@ def positive(x):


def not_zero(x):
"""Return None if value is zero"""
if x == 0:
return
return x


def none_to_zero(x):
return x or 0
"""Return 0 if value is None"""
if x is None:
return 0
return x


def decimal_to_float(x):
"""Cast Decimal values to float"""
if isinstance(x, Decimal):
return float(x)
return x
1 change: 1 addition & 0 deletions pygal/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ def unparse_color(r, g, b, a, type):


def _adjust(hsl, attribute, percent):
"""Internal adjust function"""
hsl = list(hsl)
if attribute > 0:
hsl[attribute] = _clamp(hsl[attribute] + percent)
Expand Down
1 change: 1 addition & 0 deletions pygal/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
{{ id }}.reactive.active,
{{ id }}.active .reactive {
fill-opacity: {{ style.opacity_hover }};
stroke-width: 4;
}

{{ id }}.series text {
Expand Down
9 changes: 9 additions & 0 deletions pygal/etree.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Wrapper for seemless lxml.etree / xml.etree usage
depending on whether lxml is installed or not.
"""

import os


class Etree(object):
"""Etree wrapper using lxml.etree or standard xml.etree"""

def __init__(self):
from xml.etree import ElementTree as _py_etree
self._py_etree = _py_etree
Expand All @@ -42,10 +49,12 @@ def __getattribute__(self, attr):
return object.__getattribute__(self, attr)

def to_lxml(self):
"""Force lxml.etree to be used"""
self._etree = self._lxml_etree
self.lxml = True

def to_etree(self):
"""Force xml.etree to be used"""
self._etree = self._py_etree
self.lxml = False

Expand Down
63 changes: 55 additions & 8 deletions pygal/interpolate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,23 @@
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
"""
Interpolation
Interpolation functions
These functions takes two lists of points x and y and
returns an iterator over the interpolation between all these points
with `precision` interpolated points between each of them
"""
from __future__ import division
from math import sin


def quadratic_interpolate(x, y, precision=250, **kwargs):
"""
Interpolate x, y using a quadratic algorithm
https://en.wikipedia.org/wiki/Spline_(mathematics)
"""

n = len(x) - 1
delta_x = [x2 - x1 for x1, x2 in zip(x, x[1:])]
delta_y = [y2 - y1 for y1, y2 in zip(y, y[1:])]
Expand All @@ -51,6 +60,10 @@ def quadratic_interpolate(x, y, precision=250, **kwargs):


def cubic_interpolate(x, y, precision=250, **kwargs):
"""
Interpolate x, y using a cubic algorithm
https://en.wikipedia.org/wiki/Spline_interpolation
"""
n = len(x) - 1
# Spline equation is a + bx + cx² + dx³
# ie: Spline part i equation is a[i] + b[i]x + c[i]x² + d[i]x³
Expand Down Expand Up @@ -91,6 +104,25 @@ def cubic_interpolate(x, y, precision=250, **kwargs):

def hermite_interpolate(x, y, precision=250,
type='cardinal', c=None, b=None, t=None):
"""
Interpolate x, y using the hermite method.
See https://en.wikipedia.org/wiki/Cubic_Hermite_spline
This interpolation is configurable and contain 4 subtypes:
* Catmull Rom
* Finite Difference
* Cardinal
* Kochanek Bartels
The cardinal subtype is customizable with a parameter:
* c: tension (0, 1)
This last type is also customizable using 3 parameters:
* c: continuity (-1, 1)
* b: bias (-1, 1)
* t: tension (-1, 1)
"""
n = len(x) - 1
m = [1] * (n + 1)
w = [1] * (n + 1)
Expand Down Expand Up @@ -148,6 +180,10 @@ def p(i, x_):


def lagrange_interpolate(x, y, precision=250, **kwargs):
"""
Interpolate x, y using Lagrange polynomials
https://en.wikipedia.org/wiki/Lagrange_polynomial
"""
n = len(x) - 1
delta_x = [x2 - x1 for x1, x2 in zip(x, x[1:])]
for i in range(n + 1):
Expand All @@ -170,7 +206,10 @@ def lagrange_interpolate(x, y, precision=250, **kwargs):


def trigonometric_interpolate(x, y, precision=250, **kwargs):
"""As per http://en.wikipedia.org/wiki/Trigonometric_interpolation"""
"""
Interpolate x, y using trigonometric
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):
Expand All @@ -191,12 +230,6 @@ def trigonometric_interpolate(x, y, precision=250, **kwargs):
s += y[k] * p
yield X, s

"""
These functions takes two lists of points x and y and
returns an iterator over the interpolation between all these points
with `precision` interpolated points between each of them
"""
INTERPOLATIONS = {
'quadratic': quadratic_interpolate,
'cubic': cubic_interpolate,
Expand All @@ -213,4 +246,18 @@ def trigonometric_interpolate(x, y, precision=250, **kwargs):
xy.add('normal', points)
xy.add('quadratic', quadratic_interpolate(*zip(*points)))
xy.add('cubic', cubic_interpolate(*zip(*points)))
xy.add('lagrange', lagrange_interpolate(*zip(*points)))
xy.add('trigonometric', trigonometric_interpolate(*zip(*points)))
xy.add('hermite catmul_rom', hermite_interpolate(
*zip(*points), type='catmul_rom'))
xy.add('hermite finite_difference', hermite_interpolate(
*zip(*points), type='finite_difference'))
xy.add('hermite cardinal -.5', hermite_interpolate(
*zip(*points), type='cardinal', c=-.5))
xy.add('hermite cardinal .5', hermite_interpolate(
*zip(*points), type='cardinal', c=.5))
xy.add('hermite kochanek_bartels .5 .75 -.25', hermite_interpolate(
*zip(*points), type='kochanek_bartels', c=.5, b=.75, t=-.25))
xy.add('hermite kochanek_bartels .25 -.75 .5', hermite_interpolate(
*zip(*points), type='kochanek_bartels', c=.25, b=-.75, t=.5))
xy.render_in_browser()

0 comments on commit 09480b5

Please sign in to comment.