Skip to content

Commit

Permalink
Cleanup lattice API.
Browse files Browse the repository at this point in the history
  • Loading branch information
onyxfish committed May 20, 2016
1 parent 93398b1 commit b19bec8
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 38 deletions.
10 changes: 8 additions & 2 deletions docs/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,15 @@ Chart grids
With mixed scales
-----------------

TKTK
.. literalinclude:: ../examples/grid.py
:language: python

.. figure:: ../examples/charts/grid.svg

With consistent scales
----------------------

TKTK
.. literalinclude:: ../examples/lattice.py
:language: python

.. figure:: ../examples/charts/lattice.svg
2 changes: 1 addition & 1 deletion examples/charts/colorized_dots.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions examples/charts/grid.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions examples/charts/lattice.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions examples/grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import leather

data1 = [
(0, 3),
(4, 5),
(7, 9),
(8, 4)
]

data2 = [
(3, 4),
(5, 6),
(7, 10),
(8, 2)
]

chart1 = leather.Chart('Dots')
chart1.add_dots(data1)

chart2 = leather.Chart('Lines')
chart2.add_lines(data2)

grid = leather.Grid()
grid.add_chart(chart1)
grid.add_chart(chart2)
grid.to_svg('examples/charts/grid.svg')
28 changes: 28 additions & 0 deletions examples/lattice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import leather

data1 = [
(0, 3),
(4, 5),
(7, 9),
(8, 4)
]

data2 = [
(3, 4),
(3, 4),
(5, 6),
(7, 10),
(8, 2)
]

data3 = [
(2, 4),
(3, 5),
(6, 2),
(8, 3),
(10, 5)
]

lattice = leather.Lattice()
lattice.add_many([data1, data2, data3], titles=['First', 'Second', 'Third'])
lattice.to_svg('examples/charts/lattice.svg')
4 changes: 2 additions & 2 deletions leather/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ def to_svg(self, path=None, width=None, height=None):
columns = math.ceil(math.sqrt(count))
rows = math.ceil(count / columns)

width = columns * theme.default_width
height = rows * theme.default_height
width = columns * theme.default_chart_width
height = rows * theme.default_chart_height

root = ET.Element('svg',
width=six.text_type(width),
Expand Down
83 changes: 50 additions & 33 deletions leather/lattice.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,78 @@
from leather.grid import Grid
from leather.scales import Scale
from leather.series import Series
from leather.utils import X, Y
from leather.shapes import Lines
from leather import theme
from leather.utils import DIMENSIONS, X, Y


class Lattice(object):
"""
A grid of charts with synchronized scales and axes.
A grid of charts with synchronized shapes, scales, and axes.
Lattice only supports graphing a single series of data.
:param data:
A sequence of chart data sequences.
:param shape:
An instance of :class:`.Shape` to use to render all series.
:param titles:
An optional sequence of titles to be rendered above each chart.
An instance of :class:`.Shape` to use to render all series. Defaults
to :class:`.Lines` if not specified.
"""
def __init__(self, data, shape, titles=None):
self._data = data
self._shape = shape
self._titles = titles
def __init__(self, shape=None):
self._shape = shape or Lines(theme.default_series_colors[0])
self._series = []
self._types = [None, None]

def _validate_dimension(self, dimension, chart_series):
def add_one(self, data, x=None, y=None, title=None):
"""
Verify all series have the same data types and generate a scale to fit
all the data.
Add a data series to this lattice.
:param data:
A sequence of data suitable for constructing a :class:`.Series`,
or a sequence of such objects.
:param x:
See :class:`.Series`.
:param y:
See :class:`.Series`.
:param title:
A title to render above this chart.
"""
data_type = chart_series[0].types[dimension]
series = Series(data, self._shape, x=x, y=y, name=title)

for dimension in DIMENSIONS:
if self._types[dimension]:
if series._types[dimension] is not self._types[dimension]:
raise TypeError('All data series must have the same data types.')
else:
self._types[dimension] = series._types[dimension]

for series in chart_series[1:]:
if series.types[dimension] is not data_type:
raise TypeError('All series must have the same data types.')
self._series.append(series)

return Scale.infer(chart_series, dimension, data_type)
def add_many(self, data, x=None, y=None, titles=None):
"""
Same as :meth:`.add_one` except :code:`data` is a list of data series
to be added simultaneously.
See :meth:`.add_one` for other arguments.
Note that :code:`titles` is a sequence of titles that must be the same
length as :code:`data`.
"""
for i, d in enumerate(data):
title = titles[i] if titles else None
self.add_one(d, x=x, y=y, title=title)

def to_svg(self, path=None, width=None, height=None):
"""
Render the grid to an SVG.
See :class:`.Grid` for additional documentation.
"""
chart_series = []

for seq in self._data:
chart_series.append(Series(seq, self._shape))

x_scale = self._validate_dimension(X, chart_series)
y_scale = self._validate_dimension(Y, chart_series)
x_scale = Scale.infer(self._series, X, self._types[X])
y_scale = Scale.infer(self._series, Y, self._types[Y])

grid = Grid()

for i, series in enumerate(chart_series):
if self._titles:
title = self._titles[i]
else:
title = None

chart = Chart(title)
for i, series in enumerate(self._series):
chart = Chart(title=series._name)
chart.set_x_scale(x_scale)
chart.set_y_scale(y_scale)
chart.add_series(series)
Expand Down

0 comments on commit b19bec8

Please sign in to comment.