Browse Source

Work on log scale + minor fixes

pull/8/head
Florian Mounier 13 years ago
parent
commit
6d9bcd5ef7
  1. 25
      demo/simple_test.py
  2. 2
      pygal/css/graph.css
  3. 20
      pygal/graph/base.py
  4. 4
      pygal/graph/line.py
  5. 53
      pygal/test/test_config.py
  6. 2
      pygal/view.py

25
demo/simple_test.py

@ -32,7 +32,7 @@ bar.add('inc', [None, 1, None, 2])
bar.x_labels = map(str, rng)
bar.fill = True
bar.render_to_file('out-bar.svg')
# bar.render_to_file('out-bar.svg')
hbar = HorizontalBar()
rng = [18, 9, 7, 3, 1, None, -5]
@ -44,7 +44,7 @@ hbar.add('test3', rng3)
hbar.x_labels = map(
lambda x: '%s / %s' % x, zip(map(str, rng), map(str, rng2)))
hbar.title = "Horizontal Bar test"
hbar.render_to_file('out-horizontalbar.svg')
# hbar.render_to_file('out-horizontalbar.svg')
rng = [3, -32, 39, 12]
rng2 = [24, -8, 18, 12]
@ -63,18 +63,18 @@ stackedbar.add('@@@@@@@', rng)
stackedbar.add('++++++', rng2)
stackedbar.add('--->', rng3)
stackedbar.add('None', [None, 42, 42])
stackedbar.render_to_file('out-stackedbar.svg')
# stackedbar.render_to_file('out-stackedbar.svg')
config.title = "Horizontal Stacked Bar test"
hstackedbar = HorizontalStackedBar(config)
hstackedbar.add('@@@@@@@', rng)
hstackedbar.add('++++++', rng2)
hstackedbar.add('--->', rng3)
hstackedbar.render_to_file('out-horizontalstackedbar.svg')
# hstackedbar.render_to_file('out-horizontalstackedbar.svg')
line = Line(Config(style=NeonStyle,
zero=1, fill=True,
human_readable=True, logarithmic=True))
zero=.0001, fill=True,
human_readable=not True, logarithmic=True))
rng = range(-30, 31, 1)
# line.add('test1', [1000 ** cos(x / 10.) for x in rng])
@ -88,7 +88,10 @@ rng = range(-30, 31, 1)
# line.add('2', [None, None, 2, 4, 8, None, 14, 10, None])
# line.add('1', [1, 5, 3, 4, 6, 12, 13, 7, 2])
# line.add('1', [.000000091, .000000094, .000092])
line.add('_', [12, 200001, 12])
# line.add('_', [2 ** -3, 2.9 ** -8, 2])
# line.add('_', [.001, .0001, .00001])
# line.add('_', [1 + 10 ** 10, 3 + 10 ** 10, 2 + 10 ** 10])
line.add('_', [1, -4, 2, 8, -2])
line.x_labels = map(str, rng)
line.title = "Line test"
# line.interpolate = "cubic"
@ -102,7 +105,7 @@ stackedline.add('test3', [9, 3, 2, 10, 8, 2])
stackedline.x_labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
stackedline.title = "Stackedline test"
stackedline.interpolate = "cubic"
stackedline.render_to_file('out-stackedline.svg')
# stackedline.render_to_file('out-stackedline.svg')
xy = XY(Config(fill=True, style=NeonStyle, interpolate='cubic'))
xy.add('test1', [(1981, 1), (1999, -4), (2001, 2), (2003, 10), (2012, 8)])
@ -111,7 +114,7 @@ xy.add('test2', [(None, None), (None, 12), (2007, None), (2002.3, 12)])
# xy.add('test2', [(1980, 0), (1985, 2), (1995, -2), (2005, 4), (2020, -4)])
# (2005, 6), (2010, -6), (2015, 3), (2020, -3), (2025, 0)])
xy.title = "XY test"
xy.render_to_file('out-xy.svg')
# xy.render_to_file('out-xy.svg')
pie = Pie(Config(style=NeonStyle))
pie.add('test', [11, 8, 21])
@ -121,7 +124,7 @@ pie.add('test4', [20, 18, 9])
pie.add('test5', [17, 5, 10])
pie.add('test6', [None, None, 10])
pie.title = "Pie test"
pie.render_to_file('out-pie.svg')
# pie.render_to_file('out-pie.svg')
config = Config()
config.fill = True
@ -135,4 +138,4 @@ radar.add('test2', [10, 2, 0, 5, 1, 9, 4])
radar.title = "Radar test"
radar.render_to_file('out-radar.svg')
# radar.render_to_file('out-radar.svg')

2
pygal/css/graph.css

@ -90,7 +90,7 @@ text.no_data {
}
.axis.y .logarithmic text:not(.major) {
opacity: 0;
font-size: 50%;
}
.axis .line {

20
pygal/graph/base.py

@ -29,10 +29,19 @@ class BaseGraph(object):
min_order = int(floor(log10(min_)))
max_order = int(ceil(log10(max_)))
positions = []
amplitude = max_order - min_order
if amplitude <= 1:
return []
detail = 10.
while amplitude * detail < 20:
detail *= 2
while amplitude * detail > 50:
detail /= 2
for order in range(min_order, max_order + 1):
for i in range(10):
tick = i * 10 ** order
if min_ <= tick <= max_:
for i in range(int(detail)):
tick = (10 * i / detail or 1.) * 10 ** order
tick = round_to_scale(tick, tick)
if min_ <= tick <= max_ and tick not in positions:
positions.append(tick)
return positions
@ -42,7 +51,10 @@ class BaseGraph(object):
if max_ - min_ == 0:
return [min_]
if self.logarithmic:
return self._compute_logarithmic_scale(min_, max_)
log_scale = self._compute_logarithmic_scale(min_, max_)
if log_scale:
return log_scale
# else we fallback to normal scalling
order = round(log10(max(abs(min_), abs(max_)))) - 1
while (max_ - min_) / float(10 ** order) < min_scale:
order -= 1

4
pygal/graph/line.py

@ -34,12 +34,12 @@ class Line(Graph):
return [val[1]
for serie in self.series
for val in serie.interpolated
if val[1] != None]
if val[1] != None and (not self.logarithmic or val[1] > 0)]
else:
return [val[1]
for serie in self.series
for val in serie.points
if val[1] != None]
if val[1] != None and (not self.logarithmic or val[1] > 0)]
def _fill(self, values):
zero = self.view.y(min(max(self.zero, self._box.ymin), self._box.ymax))

53
pygal/test/test_config.py

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# This file is part of pygal
#
# A python svg graph plotting library
# Copyright © 2012 Kozea
#
# This library is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pygal. If not, see <http://www.gnu.org/licenses/>.
from pygal import Line
def test_logarithmic():
line = Line(logarithmic=True)
line.add('_', [1, 10 ** 10, 1])
q = line.render_pyquery()
assert len(q(".axis.x")) == 0
assert len(q(".axis.y")) == 1
assert len(q(".plot .series path")) == 1
assert len(q(".legend")) == 1
assert len(q(".x.axis .guides")) == 0
assert len(q(".y.axis .guides")) == 51
assert len(q(".dots")) == 3
def test_logarithmic_bad_interpolation():
line = Line(logarithmic=True, interpolate='cubic')
line.add('_', [.001, .00000001, 1])
q = line.render_pyquery()
assert len(q(".y.axis .guides")) == 40
def test_logarithmic_big_scale():
line = Line(logarithmic=True)
line.add('_', [10 ** -10, 10 ** 10, 1])
q = line.render_pyquery()
assert len(q(".y.axis .guides")) == 41
def test_logarithmic_small_scale():
line = Line(logarithmic=True)
line.add('_', [1 + 10 ** 10, 3 + 10 ** 10, 2 + 10 ** 10])
q = line.render_pyquery()
assert len(q(".y.axis .guides")) == 21

2
pygal/view.py

@ -114,7 +114,7 @@ class LogView(View):
self.box.fix(False)
def y(self, y):
if y == None:
if y == None or y <= 0:
return None
return (self.height - self.height *
(log10(y) - self.log10_ymin)

Loading…
Cancel
Save