Skip to content

Merge convert-numeric into encodings #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 88 commits into from
Jul 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
6a30be1
Add x, y, and color channel conversion
kdorr Jun 27, 2018
c900832
New approach for organization
kdorr Jun 27, 2018
9b10372
Add locate data function
kdorr Jun 28, 2018
2e279f0
Get x, y, size, color, opacity, and shape working
kdorr Jun 29, 2018
9251325
Get x2, y2, fill, and stroke working
kdorr Jun 29, 2018
ca5fb9f
Convert x and y channels
kdorr Jul 2, 2018
92f72ea
Convert color, fill, opacity, shape, size, and stroke
kdorr Jul 3, 2018
859ce08
Convert x2, y2
kdorr Jul 3, 2018
142c329
Adds module to handle the data
palnabarun Jul 3, 2018
7664992
Adds tests for the data module
palnabarun Jul 3, 2018
c905f62
Adds utilities module
palnabarun Jul 3, 2018
44a0352
Adds tests for the _utils module
palnabarun Jul 3, 2018
1a1abd3
Adds boilerplate
palnabarun Jul 3, 2018
90031eb
Adds x encoding channel mapping
palnabarun Jul 3, 2018
1edcc73
Adds test for x encoding mapping
palnabarun Jul 3, 2018
f319422
Adds y encoding channel
palnabarun Jul 3, 2018
698d166
Adds tests for y encoding channel
palnabarun Jul 3, 2018
6cc1af0
Refactores the code
palnabarun Jul 3, 2018
2d78b46
Adds color encoding channel
palnabarun Jul 3, 2018
bc6156a
Adds tests for color encoding channel
palnabarun Jul 3, 2018
c27b627
Adds fill encoding channel
palnabarun Jul 3, 2018
136bc9c
Adds tests for fill encoding channel
palnabarun Jul 3, 2018
93aa3a6
Adds size encoding channel
palnabarun Jul 3, 2018
4969a9f
Adds size encoding channel
palnabarun Jul 3, 2018
388f1e9
Convert dates to matplotlib dates
kdorr Jul 3, 2018
42f59d3
Add timeUnit handling
kdorr Jul 3, 2018
4782258
Merge branch 'master' into convert-numeric
story645 Jul 3, 2018
c473982
Merge branch 'master' into encodings
story645 Jul 3, 2018
d75353e
Merge branch 'master' into convert-temporal
story645 Jul 3, 2018
755a718
Adds module to handle the data
palnabarun Jul 3, 2018
52ae0af
Adds tests for the data module
palnabarun Jul 3, 2018
3f15b0e
Adds utilities module
palnabarun Jul 3, 2018
3c5e415
Adds tests for the _utils module
palnabarun Jul 3, 2018
ee57614
Adds boilerplate
palnabarun Jul 3, 2018
42eafd4
Adds x encoding channel mapping
palnabarun Jul 3, 2018
4a79fda
Adds test for x encoding mapping
palnabarun Jul 3, 2018
b1afe0f
Adds y encoding channel
palnabarun Jul 3, 2018
8e3d2a3
Adds tests for y encoding channel
palnabarun Jul 3, 2018
85c0fca
Refactores the code
palnabarun Jul 3, 2018
54e3b76
Adds color encoding channel
palnabarun Jul 3, 2018
dd712af
Adds tests for color encoding channel
palnabarun Jul 3, 2018
6e03468
Adds fill encoding channel
palnabarun Jul 3, 2018
116e6a1
Adds tests for fill encoding channel
palnabarun Jul 3, 2018
2ef6a40
Adds size encoding channel
palnabarun Jul 3, 2018
a3c76e7
Adds size encoding channel
palnabarun Jul 3, 2018
a3c9963
Merge branch 'encodings' of github.com:palnabarun/mpl-altair into enc…
palnabarun Jul 4, 2018
2d6bb92
Adds vega-datasets to test_requirements
palnabarun Jul 4, 2018
8a6751c
Refactor
kdorr Jul 4, 2018
6b928e0
Add tests for locating data
kdorr Jul 4, 2018
c78e242
Clean up tests
kdorr Jul 4, 2018
69a3fda
Add tests for data
kdorr Jul 4, 2018
db4e617
Refactor
kdorr Jul 4, 2018
ddad659
Merge branch 'convert-temporal' of https://github.com/kdorr/mpl-altai…
kdorr Jul 4, 2018
33d4e10
Merge branch 'convert-numeric' of https://github.com/kdorr/mpl-altair…
kdorr Jul 4, 2018
2525a93
Merge branch 'master' into convert-temporal
story645 Jul 5, 2018
481fb18
Merge branch 'master' into convert-numeric
story645 Jul 5, 2018
affb7a0
Merge branch 'master' into encodings
story645 Jul 5, 2018
ccb9f72
Refactor: rename for merge and remove lambdas
kdorr Jul 5, 2018
8e47685
Merge branch 'convert-numeric' into encodings
kdorr Jul 6, 2018
a15e240
Fix merge issues
kdorr Jul 6, 2018
fa1920f
Merge branch 'master' into encodings
palnabarun Jul 7, 2018
345bbb8
Refactors test to use .to_dict instead of .to_json
palnabarun Jul 7, 2018
2877539
Merge branch 'encodings' of github.com:palnabarun/mpl-altair into enc…
palnabarun Jul 7, 2018
94c3193
Refactors tests to use pytest.marks.parametrize
palnabarun Jul 7, 2018
45b67d7
Converts mplaltair._convert.convert to mplaltair._convert._convert
palnabarun Jul 9, 2018
8d9ccc1
Imports internal convert functionality to _convert
palnabarun Jul 9, 2018
9fae447
Refactors public convert utility
palnabarun Jul 9, 2018
4e1cdbc
Refactors tests to use public API instead
palnabarun Jul 9, 2018
911f6a7
Adds ValidationError Exception class
palnabarun Jul 9, 2018
a4f4e95
Uses ValidationError at appropriate places
palnabarun Jul 9, 2018
eca1cff
Modifies ValidationError exception class definition
palnabarun Jul 9, 2018
2f2483e
Merge branch 'encodings' of git://github.com/palnabarun/mpl-altair in…
kdorr Jul 9, 2018
c16bf62
Merge fix
kdorr Jul 9, 2018
afa3868
Merge remote-tracking branch 'origin/convert-temporal' into encodings
kdorr Jul 9, 2018
7539c70
Add tests for _data._locate_channel_dtype
kdorr Jul 9, 2018
9ef83f4
Combine test_convert_quantitative.py with test_convert.py
kdorr Jul 9, 2018
23a2a71
Merge branch 'master' into encodings
story645 Jul 11, 2018
437ce42
Merge branch 'master' into encodings
story645 Jul 11, 2018
4f1babd
Fixes failing tests in mpolaltair.tests.test_data
palnabarun Jul 11, 2018
ae65141
Removes Python 2 fallback code
palnabarun Jul 16, 2018
267b5d2
Add coverage tests
kdorr Jul 16, 2018
6e05448
Removes redundant code
palnabarun Jul 17, 2018
15039e3
Improves test coverage
palnabarun Jul 17, 2018
43da507
Refactor: make _locate functions nicer
kdorr Jul 17, 2018
9a72a85
Add encoding checks
kdorr Jul 17, 2018
02d5149
Add coverage tests
kdorr Jul 17, 2018
1c5dbca
Merge branch 'encodings' of git://github.com/palnabarun/mpl-altair in…
kdorr Jul 17, 2018
fbe3b61
Merge branch 'encodings' of https://github.com/kdorr/mpl-altair into …
kdorr Jul 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
branch = true
source =
mplaltair
omit = *tests*

[report]
exclude_lines =
Expand Down
22 changes: 5 additions & 17 deletions mplaltair/__init__.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,23 @@
import matplotlib
import altair

from ._convert import _convert

# TODO rename this?
def convert(encoding, *, figure=None):
def convert(chart):
"""Convert an altair encoding to a Matplotlib figure


Parameters
----------
encoding
The Altair encoding of the plot.

figure : matplotib.figure.Figure, optional
# TODO: generalize this to 'thing that supports gridspec slicing?
chart
The Altair chart object generated by Altair

Returns
-------
figure : matplotlib.figure.Figure
The Figure with all artists in it (ready to be saved or shown)

mapping : dict
Mapping from parts of the encoding to the Matplotlib artists. This is
for later customization.


"""
if figure is None:
from matplotlib import pyplot as plt
figure = plt.figure()

mapping = {}

return figure, mapping
return _convert(chart)
128 changes: 128 additions & 0 deletions mplaltair/_convert.py
Original file line number Diff line number Diff line change
@@ -1 +1,129 @@
import matplotlib.dates as mdates
from ._data import _locate_channel_data, _locate_channel_dtype

def _allowed_ranged_marks(enc_channel, mark):
"""TODO: DOCS
"""
return mark in ['area', 'bar', 'rect', 'rule'] if enc_channel in ['x2', 'y2'] else True

def _process_x(dtype, data):
"""Returns the MPL encoding equivalent for Altair x channel
"""
return ('x', data)


def _process_y(dtype, data):
"""Returns the MPL encoding equivalent for Altair y channel
"""
return ('y', data)


def _process_x2(dtype, data):
"""Returns the MPL encoding equivalent for Altair x2 channel
"""
raise NotImplementedError


def _process_y2(dtype, data):
"""Returns the MPL encoding equivalent for Altair y2 channel
"""
raise NotImplementedError


def _process_color(dtype, data):
"""Returns the MPL encoding equivalent for Altair color channel
"""
if dtype == 'quantitative':
return ('c', data)
elif dtype == 'nominal':
raise NotImplementedError
elif dtype == 'ordinal':
return ('c', data)
else: # temporal
return ('c', data)


def _process_fill(dtype, data):
"""Returns the MPL encoding equivalent for Altair fill channel
"""
return _process_color(dtype, data)


def _process_shape(dtype, data):
"""Returns the MPL encoding equivalent for Altair shape channel
"""
raise NotImplementedError


def _process_opacity(dtype, data):
"""Returns the MPL encoding equivalent for Altair opacity channel
"""
raise NotImplementedError


def _process_size(dtype, data):
"""Returns the MPL encoding equivalent for Altair size channel
"""
if dtype == 'quantitative':
return ('s', data)
elif dtype == 'nominal':
raise NotImplementedError
elif dtype == 'ordinal':
return ('s', data)
elif dtype == 'temporal':
raise NotImplementedError


def _process_stroke(dtype, data):
"""Returns the MPL encoding equivalent for Altair stroke channel
"""
raise NotImplementedError

_mappings = {
'x': _process_x,
'y': _process_y,
'x2': _process_x2,
'y2': _process_y2,
'color': _process_color,
'fill': _process_fill,
'shape': _process_shape,
'opacity': _process_opacity,
'size': _process_size,
'stroke': _process_stroke,
}

def _convert(chart):
"""Convert an altair encoding to a Matplotlib figure


Parameters
----------
chart
The Altair chart.

Returns
-------
mapping : dict
Mapping from parts of the encoding to the Matplotlib artists. This is
for later customization.
"""
mapping = {}

if not chart.to_dict().get('encoding'):
raise ValueError("Encoding not provided with the chart specification")

for enc_channel, enc_spec in chart.to_dict()['encoding'].items():
if not _allowed_ranged_marks(enc_channel, chart.to_dict()['mark']):
raise ValueError("Ranged encoding channels like x2, y2 not allowed for Mark: {}".format(chart['mark']))

for channel in chart.to_dict()['encoding']:
data = _locate_channel_data(chart, channel)
dtype = _locate_channel_dtype(chart, channel)
if dtype == 'temporal':
try:
data = mdates.date2num(data) # Convert dates to Matplotlib dates
except AttributeError:
raise
mapping[_mappings[channel](dtype, data)[0]] = _mappings[channel](dtype, data)[1]

return mapping
64 changes: 64 additions & 0 deletions mplaltair/_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from ._exceptions import ValidationError

def _locate_channel_dtype(chart, channel):
"""Locates dtype used for each channel
Parameters
----------
chart
The Altair chart
channel
The Altair channel being examined

Returns
-------
A string representing the data type from the Altair chart ('quantitative', 'ordinal', 'numeric', 'temporal')
"""

channel_val = chart.to_dict()['encoding'][channel]
if channel_val.get('type'):
return channel_val.get('type')
else:
# TODO: find some way to deal with 'value' so that, opacity, for instance, can be plotted with a value defined
if channel_val.get('value'):
raise NotImplementedError
raise NotImplementedError


def _locate_channel_data(chart, channel):
"""Locates data used for each channel

Parameters
----------
chart
The Altair chart
channel
The Altair channel being examined

Returns
-------
A numpy ndarray containing the data used for the channel

Raises
------
ValidationError
Raised when the specification does not contain any data attribute

"""

channel_val = chart.to_dict()['encoding'][channel]
if channel_val.get('value'):
return channel_val.get('value')
elif channel_val.get('aggregate'):
return _aggregate_channel()
elif channel_val.get('timeUnit'):
return _handle_timeUnit()
else: # field is required if the above are not present.
return chart.data[channel_val.get('field')].values


def _aggregate_channel():
raise NotImplementedError


def _handle_timeUnit():
raise NotImplementedError
2 changes: 2 additions & 0 deletions mplaltair/_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class ValidationError(Exception):
pass
Loading