Skip to content

Instantly share code, notes, and snippets.

@kdorr
Created Aug 8, 2018
Embed
What would you like to do?
def _line_division(chart, ax):
"""Convert encodings, manipulate data if needed, plot on ax.
Parameters
----------
chart : altair.Chart
The Altair chart object
ax
The Matplotlib axes object
Notes
-----
Fill isn't necessary until mpl-altair can handle multiple plot types in one plot.
Size is unsupported by both Matplotlib and Altair.
When both Color and Stroke are provided, color is ignored and stroke is used.
Shape is unsupported in line graphs unless another plot type is plotted at the same time.
Opacity still needs to be implemented.
"""
if chart.to_dict()['encoding'].get('opacity'):
raise NotImplementedError("Still need to implement.")
# dtype = _locate_channel_dtype(chart, 'opacity')
# normalize opacity values to (0,1)
# mapping['kwargs'] = {'alpha': normalized_vals} # ish (not really going to work)
if chart.to_dict()['encoding'].get('stroke'):
grouping = chart.to_dict()['encoding']['stroke']['field']
elif chart.to_dict()['encoding'].get('color'): # If both color and stroke are encoded, color is ignored.
grouping = chart.to_dict()['encoding']['color']['field']
else:
mapping = _convert(chart)
ax.plot(*mapping['args'])
return
for lab, subset in chart.data.groupby(grouping):
tmp_chart = chart
tmp_chart.data = subset
mapping = _convert(tmp_chart)
mapping['kwargs'] = {'label': lab} # for legend purposes later on
_line_mapping = {
'x': lambda d: ('x', d),
'y': lambda d: ('y', d),
'args': lambda x, y: [x, y]
}
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)
# FROM AXIS-NUMERIC============================================================================================
if dtype == 'temporal':
data = _convert_to_mpl_date(data)
# END STUFF FROM AXIS-NUMERIC==================================================================================
"""
if dtype == 'temporal':
try:
data = mdates.date2num(data) # Convert dates to Matplotlib dates
except AttributeError:
raise
"""
if chart.mark in ['point', 'circle', 'square']:
mapping[_mappings[channel](dtype, data)[0]] = _mappings[channel](dtype, data)[1]
elif chart.mark == 'line' and channel in ['x', 'y']:
mapping[_line_mapping[channel](data)[0]] = _line_mapping[channel](data)[1]
if chart.mark == 'line':
mapping['args'] = _line_mapping['args'](mapping['x'], mapping['y']) # plot() doesn't take kwargs for x and y
return mapping
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment