From fcb6af4f4ff894850170ab1470dd4602ae411d3b Mon Sep 17 00:00:00 2001 From: Nabarun Pal Date: Thu, 26 Jul 2018 20:38:30 +0530 Subject: [PATCH 1/5] Adds axis label setters --- mplaltair/_axis.py | 25 +++++++++++++++++++++++++ mplaltair/parse_chart.py | 2 ++ 2 files changed, 27 insertions(+) diff --git a/mplaltair/_axis.py b/mplaltair/_axis.py index 87fbf3f..f4df806 100644 --- a/mplaltair/_axis.py +++ b/mplaltair/_axis.py @@ -209,6 +209,30 @@ def _set_label_angle(channel, ax): label.set_rotation(30) label.set_ha('right') +def _set_axis_title(channel, ax): + '''Sets the axis label + + Currently, does not support aggregated, binned or timeUnit specified channels + + Parameters + ---------- + channel: parse_chart.ChannelMetadata + The channel data and metadata + ax: maptlotlib.axes + The matplotlib axis to be modified + ''' + if channel.title: + if channel.name == 'x': + ax.set_xlabel(title) + elif channel.name == 'y': + ax.set_ylabel(title) + elif channel.aggregate: + raise NotImplementedError + elif channel.bin: + raise NotImplementedError + elif channel.timeUnit: + raise NotImplementedError + def convert_axis(ax, chart): """Convert elements of the altair chart to Matplotlib axis properties @@ -226,3 +250,4 @@ def convert_axis(ax, chart): _set_tick_locator(channel, ax) _set_tick_formatter(channel, ax) _set_label_angle(channel, ax) + _set_axis_title(channel, ax) diff --git a/mplaltair/parse_chart.py b/mplaltair/parse_chart.py index 2ea5171..afa526d 100644 --- a/mplaltair/parse_chart.py +++ b/mplaltair/parse_chart.py @@ -11,6 +11,7 @@ class ChannelMetadata(object): The name of the encoding channel data : np.array The data linked to the channel (temporal data is converted) + aggregate : str or dict axis : dict bin : boolean, None field : str @@ -25,6 +26,7 @@ def __init__(self, channel, alt_chart): chart_dict = alt_chart.to_dict() self.name = channel self.data = self._locate_channel_data(alt_chart) + self.aggregate = chart_dict['encoding'][self.name].get('aggregate', {}) self.axis = chart_dict['encoding'][self.name].get('axis', {}) self.bin = chart_dict['encoding'][self.name].get('bin', None) self.field = chart_dict['encoding'][self.name].get('field', None) From fb0c0e14921598eaa9cf5441de09945d7f06116d Mon Sep 17 00:00:00 2001 From: Nabarun Pal Date: Tue, 31 Jul 2018 18:39:33 +0530 Subject: [PATCH 2/5] Raises if default config of axis and scales are overriden --- mplaltair/parse_chart.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mplaltair/parse_chart.py b/mplaltair/parse_chart.py index afa526d..189a098 100644 --- a/mplaltair/parse_chart.py +++ b/mplaltair/parse_chart.py @@ -114,6 +114,13 @@ def __init__(self, alt_chart): self.data = alt_chart.data self.mark = alt_chart.mark + if alt_chart.to_dict().get('config').get('axis'): + raise NotImplementedError + + if alt_chart.to_dict().get('config').get('scale'): + raise NotImplementedError + + self.encoding = {} for k, v in alt_chart.to_dict()['encoding'].items(): self.encoding[k] = ChannelMetadata(k, alt_chart) \ No newline at end of file From f8add249223df9cfd655e6bcf01be53d2cdd8070 Mon Sep 17 00:00:00 2001 From: Nabarun Pal Date: Fri, 3 Aug 2018 21:16:10 +0530 Subject: [PATCH 3/5] Adds axis.labels functionality --- mplaltair/_axis.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/mplaltair/_axis.py b/mplaltair/_axis.py index f4df806..7930ea4 100644 --- a/mplaltair/_axis.py +++ b/mplaltair/_axis.py @@ -233,6 +233,22 @@ def _set_axis_title(channel, ax): elif channel.timeUnit: raise NotImplementedError +def _set_axis_label_visibility(channel, ax): + '''Set the axis label visibility + + Parameters + ---------- + channel: parse_chart.ChannelMetadata + The channel data and metadata + ax: maptlotlib.axes + The matplotlib axis to be modified + ''' + labels = channel.axis.get('labels', True) + + if channel.name == 'x': + ax.tick_param(labelbottom=labels, labeltop=labels) + elif channel.name == 'y': + ax.tick_param(labelleft=labels, labelright=labels) def convert_axis(ax, chart): """Convert elements of the altair chart to Matplotlib axis properties @@ -251,3 +267,4 @@ def convert_axis(ax, chart): _set_tick_formatter(channel, ax) _set_label_angle(channel, ax) _set_axis_title(channel, ax) + _set_axis_label_visibility(channel, ax) From 5f84228b1c4024f025aa8569bab8ca1ef2465684 Mon Sep 17 00:00:00 2001 From: Nabarun Pal Date: Fri, 3 Aug 2018 21:16:41 +0530 Subject: [PATCH 4/5] Adds axis.labelAngle functionality --- mplaltair/_axis.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mplaltair/_axis.py b/mplaltair/_axis.py index 7930ea4..557d9c2 100644 --- a/mplaltair/_axis.py +++ b/mplaltair/_axis.py @@ -203,11 +203,30 @@ def _set_label_angle(channel, ax): ax : matplotlib.axes The mapping of the axis metadata and the scale data """ + + label_angle = channel.axis.get('labelAngle') + + # Sets the defaults used by altair if axis.labelAngle is not specified + if label_angle is None: + if channel.type in ['ordinal', 'nominal']: + label_angle = -90 + elif channel_type in ['quantitative', 'temporal']: + label_angle = 0 + + if channel.name == 'x': + for label in ax.get_xticklabels(): + label.set_rotation(-1*label_angle) + elif channel.name == 'y': + for label in ax.get_yticklabels(): + label.set_rotation(-1*label_angle) + + # Special case for temporal encoding type to improve visual appeal if channel.type == 'temporal' and channel.name == 'x': for label in ax.get_xticklabels(): # Rotate the labels on the x-axis so they don't run into each other. label.set_rotation(30) label.set_ha('right') + def _set_axis_title(channel, ax): '''Sets the axis label From e86df6f42e3a1728888f8220a735d45052a3cd0c Mon Sep 17 00:00:00 2001 From: Nabarun Pal Date: Fri, 3 Aug 2018 21:54:15 +0530 Subject: [PATCH 5/5] Adds axis.orient functionality --- mplaltair/_axis.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/mplaltair/_axis.py b/mplaltair/_axis.py index 557d9c2..028d180 100644 --- a/mplaltair/_axis.py +++ b/mplaltair/_axis.py @@ -226,7 +226,6 @@ def _set_label_angle(channel, ax): # Rotate the labels on the x-axis so they don't run into each other. label.set_rotation(30) label.set_ha('right') - def _set_axis_title(channel, ax): '''Sets the axis label @@ -269,6 +268,37 @@ def _set_axis_label_visibility(channel, ax): elif channel.name == 'y': ax.tick_param(labelleft=labels, labelright=labels) +def _set_axis_orientation(channel, ax): + '''Set the axis orientation + + Parameters + ---------- + channel: parse_chart.ChannelMetadata + The channel data and metadata + ax: maptlotlib.axes + The matplotlib axis to be modified + ''' + orient = channel.axis.get('orient') + + if orient is None: + if channel.name == 'x': + orient = 'bottom' + elif channel.name == 'y': + orient = 'left' + + ACTIONS = { + 'x': { + 'top': ax.xaxis.tick_top, + 'bottom': ax.xaxis.tick_bottom + }, + 'y': { + 'left': ax.xaxis.tick_left, + 'right': ax.xaxis.tick_right + } + } + + ACTIONS[enc][orient]() + def convert_axis(ax, chart): """Convert elements of the altair chart to Matplotlib axis properties @@ -287,3 +317,4 @@ def convert_axis(ax, chart): _set_label_angle(channel, ax) _set_axis_title(channel, ax) _set_axis_label_visibility(channel, ax) + _set_axis_orientation(channel, ax)