Skip to content

Commit

Permalink
Merge remote-tracking branch 'altair-viz/master' into it-vega#588-geo…
Browse files Browse the repository at this point in the history
…pandas
  • Loading branch information
iliatimofeev committed May 16, 2018
2 parents c114acc + eb6d55b commit 143ad04
Show file tree
Hide file tree
Showing 28 changed files with 267 additions and 86 deletions.
6 changes: 6 additions & 0 deletions altair/sphinxext/altairgallery.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
Some may seem fairly complicated at first glance, but they are built by combining a simple set of declarative building blocks.
Many draw upon sample datasets compiled by the `Vega <https://vega.github.io/vega/>`_ project. To access them yourself, install `vega_datasets <https://github.com/altair-viz/vega_datasets>`_.
.. code-block::
$ pip install vega_datasets
{% for grouper, group in examples %}
.. _gallery-category-{{ grouper }}:
Expand Down
44 changes: 44 additions & 0 deletions altair/vegalite/v1/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,50 @@ def _repr_mimebundle_(self, include, exclude):
else:
return renderers.get()(dct)

def display(self):
"""Display chart in Jupyter notebook or JupyterLab"""
from IPython.display import display
display(self)

def serve(self, ip='127.0.0.1', port=8888, n_retries=50, files=None,
jupyter_warning=True, open_browser=True, http_server=None,
**kwargs):
"""Open a browser window and display a rendering of the chart
Parameters
----------
html : string
HTML to serve
ip : string (default = '127.0.0.1')
ip address at which the HTML will be served.
port : int (default = 8888)
the port at which to serve the HTML
n_retries : int (default = 50)
the number of nearby ports to search if the specified port
is already in use.
files : dictionary (optional)
dictionary of extra content to serve
jupyter_warning : bool (optional)
if True (default), then print a warning if this is used
within the Jupyter notebook
open_browser : bool (optional)
if True (default), then open a web browser to the given HTML
http_server : class (optional)
optionally specify an HTTPServer class to use for showing the
figure. The default is Python's basic HTTPServer.
**kwargs :
additional keyword arguments passed to the save() method
"""
from ...utils.server import serve

html = six.StringIO()
self.save(html, format='html', **kwargs)
html.seek(0)

serve(html.read(), ip=ip, port=port, n_retries=n_retries,
files=files, jupyter_warning=jupyter_warning,
open_browser=open_browser, http_server=http_server)


class Chart(TopLevelMixin, core.ExtendedUnitSpec):
def __init__(self, data=Undefined, encoding=Undefined, mark=Undefined,
Expand Down
6 changes: 6 additions & 0 deletions altair/vegalite/v1/schema/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ def to_dict(self, validate=True, ignore=(), context=None):
context = context or {}
if self.shorthand is Undefined:
kwds = {}
elif isinstance(self.shorthand, (tuple, list)):
# If given a list of shorthands, then transform it to a list of classes
kwds = self._kwds.copy()
kwds.pop('shorthand')
return [self.__class__(shorthand, **kwds).to_dict()
for shorthand in self.shorthand]
elif isinstance(self.shorthand, six.string_types):
kwds = parse_shorthand(self.shorthand, data=context.get('data', None))
type_defined = self._kwds.get('type', Undefined) is not Undefined
Expand Down
96 changes: 80 additions & 16 deletions altair/vegalite/v2/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,20 +421,6 @@ def __and__(self, other):
def __or__(self, other):
return HConcatChart(hconcat=[self, other])

# Display-related methods

def _repr_mimebundle_(self, include, exclude):
"""Return a MIME bundle for display in Jupyter frontends."""
# Catch errors explicitly to get around issues in Jupyter frontend
# see https://github.com/ipython/ipython/issues/11038
try:
dct = self.to_dict()
except Exception:
utils.display_traceback(in_ipython=True)
return {}
else:
return renderers.get()(dct)

def repeat(self, row=Undefined, column=Undefined, **kwargs):
"""Return a RepeatChart built from the chart
Expand Down Expand Up @@ -466,6 +452,18 @@ def properties(self, **kwargs):
setattr(copy, key, val)
return copy

def add_selection(self, *selections):
"""Add one or more selections to the chart"""
if not selections:
return self
else:
copy = self.copy(deep=True, ignore=['data'])
if copy.selection is Undefined:
copy.selection = SelectionMapping()
for selection in selections:
copy.selection += selection
return copy

def project(self, type='mercator', center=Undefined, clipAngle=Undefined, clipExtent=Undefined,
coefficient=Undefined, distance=Undefined, fraction=Undefined, lobes=Undefined,
parallel=Undefined, precision=Undefined, radius=Undefined, ratio=Undefined,
Expand Down Expand Up @@ -854,15 +852,78 @@ def resolve_legend(self, *args, **kwargs):
def resolve_scale(self, *args, **kwargs):
return self._set_resolve(scale=core.ScaleResolveMap(*args, **kwargs))

# Display-related methods

def _repr_mimebundle_(self, include, exclude):
"""Return a MIME bundle for display in Jupyter frontends."""
# Catch errors explicitly to get around issues in Jupyter frontend
# see https://github.com/ipython/ipython/issues/11038
try:
dct = self.to_dict()
except Exception:
utils.display_traceback(in_ipython=True)
return {}
else:
return renderers.get()(dct)

def display(self):
"""Display chart in Jupyter notebook or JupyterLab"""
from IPython.display import display
display(self)

def serve(self, ip='127.0.0.1', port=8888, n_retries=50, files=None,
jupyter_warning=True, open_browser=True, http_server=None,
**kwargs):
"""Open a browser window and display a rendering of the chart
Parameters
----------
html : string
HTML to serve
ip : string (default = '127.0.0.1')
ip address at which the HTML will be served.
port : int (default = 8888)
the port at which to serve the HTML
n_retries : int (default = 50)
the number of nearby ports to search if the specified port
is already in use.
files : dictionary (optional)
dictionary of extra content to serve
jupyter_warning : bool (optional)
if True (default), then print a warning if this is used
within the Jupyter notebook
open_browser : bool (optional)
if True (default), then open a web browser to the given HTML
http_server : class (optional)
optionally specify an HTTPServer class to use for showing the
figure. The default is Python's basic HTTPServer.
**kwargs :
additional keyword arguments passed to the save() method
"""
from ...utils.server import serve

html = six.StringIO()
self.save(html, format='html', **kwargs)
html.seek(0)

serve(html.read(), ip=ip, port=port, n_retries=n_retries,
files=files, jupyter_warning=jupyter_warning,
open_browser=open_browser, http_server=http_server)


class EncodingMixin(object):
@utils.use_signature(core.EncodingWithFacet)
def encode(self, *args, **kwargs):
# First convert args to kwargs by inferring the class from the argument
if args:
mapping = _get_channels_mapping()
channels_mapping = _get_channels_mapping()
for arg in args:
encoding = mapping.get(type(arg), None)
if isinstance(arg, (list, tuple)) and len(arg) > 0:
type_ = type(arg[0])
else:
type_ = type(arg)

encoding = channels_mapping.get(type_, None)
if encoding is None:
raise NotImplementedError("non-keyword arg of type {0}"
"".format(type(arg)))
Expand All @@ -880,6 +941,9 @@ def _wrap_in_channel_class(obj, prop):
if isinstance(obj, six.string_types):
obj = {'shorthand': obj}

if isinstance(obj, (list, tuple)):
return [_wrap_in_channel_class(subobj, prop) for subobj in obj]

if 'value' in obj:
clsname += 'Value'

Expand Down
4 changes: 2 additions & 2 deletions altair/vegalite/v2/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

from .schema import SCHEMA_VERSION
VEGALITE_VERSION = SCHEMA_VERSION.lstrip('v')
VEGA_VERSION = '3.2'
VEGAEMBED_VERSION = '3.0'
VEGA_VERSION = '3.3'
VEGAEMBED_VERSION = '3.9'


# ==============================================================================
Expand Down
12 changes: 6 additions & 6 deletions altair/vegalite/v2/examples/dot_dash_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,24 @@
x=alt.X('Miles_per_Gallon', axis=alt.Axis(title='')),
y=alt.Y('Horsepower', axis=alt.Axis(title='')),
color=alt.condition(brush, 'Origin', alt.value('grey'))
).properties(
selection=brush
).add_selection(
brush
)

x_ticks = alt.Chart(cars).mark_tick().encode(
alt.X('Miles_per_Gallon', axis=tick_axis),
alt.Y('Origin', axis=tick_axis_notitle),
color=alt.condition(brush, 'Origin', alt.value('lightgrey'))
).properties(
selection=brush
).add_selection(
brush
)

y_ticks = alt.Chart(cars).mark_tick().encode(
alt.X('Origin', axis=tick_axis_notitle),
alt.Y('Horsepower', axis=tick_axis),
color=alt.condition(brush, 'Origin', alt.value('lightgrey'))
).properties(
selection=brush
).add_selection(
brush
)

y_ticks | (points & x_ticks)
4 changes: 2 additions & 2 deletions altair/vegalite/v2/examples/interactive_brush.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@
x='Horsepower:Q',
y='Miles_per_Gallon:Q',
color=alt.condition(brush, 'Cylinders:O', alt.value('grey'))
).properties(
selection=brush
).add_selection(
brush
)
2 changes: 1 addition & 1 deletion altair/vegalite/v2/examples/interactive_cross_highlight.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
legend=alt.Legend(title='Records in Selection')
)
).transform_filter(
pts.ref()
pts
)

bar = alt.Chart(data.movies.url).mark_bar().encode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
highlight = base.encode(
color=alt.value('goldenrod')
).transform_filter(
brush.ref()
brush
)

# layer the two charts & repeat
Expand Down
3 changes: 2 additions & 1 deletion altair/vegalite/v2/examples/interval_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
)

lower = upper.properties(
selection=brush,
height=60
).add_selection(
brush
)

alt.vconcat(upper, lower, data=sp500)
3 changes: 2 additions & 1 deletion altair/vegalite/v2/examples/multiline_highlight.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@

points = base.mark_circle().encode(
opacity=alt.value(0)
).add_selection(
highlight
).properties(
selection=highlight,
width=600
)

Expand Down
6 changes: 3 additions & 3 deletions altair/vegalite/v2/examples/multiline_tooltip.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
selectors = alt.Chart().mark_point().encode(
x='x:Q',
opacity=alt.value(0),
).properties(
selection=nearest
).add_selection(
nearest
)

# Draw points on the line, and highlight based on selection
Expand All @@ -52,7 +52,7 @@
rules = alt.Chart().mark_rule(color='gray').encode(
x='x:Q',
).transform_filter(
nearest.ref()
nearest
)

# Put the five layers into a chart and bind the data
Expand Down
3 changes: 2 additions & 1 deletion altair/vegalite/v2/examples/scatter_linked_brush.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
base = alt.Chart(cars).mark_point().encode(
y='Miles_per_Gallon',
color=alt.condition(brush, 'Origin', alt.ColorValue('gray'))
).add_selection(
brush
).properties(
selection=brush,
width=250,
height=250
)
Expand Down
12 changes: 7 additions & 5 deletions altair/vegalite/v2/examples/seattle_weather_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@
size=alt.Size('precipitation:Q', scale=alt.Scale(range=[5, 200]))
).properties(
width=600,
height=300,
selection=brush
height=300
).add_selection(
brush
).transform_filter(
click.ref()
click
)

# Bottom panel is a bar chart of weather type
Expand All @@ -42,10 +43,11 @@
y='weather:N',
color=alt.condition(click, color, alt.value('lightgray')),
).transform_filter(
brush.ref()
brush
).properties(
width=600,
selection=click
).add_selection(
click
)

alt.vconcat(points, bars,
Expand Down
15 changes: 7 additions & 8 deletions altair/vegalite/v2/examples/select_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,23 @@

selector = alt.selection_single(empty='all', fields=['id'])

points = alt.Chart(data).mark_point(filled=True, size=200).encode(
base = alt.Chart(data).properties(
width=250,
height=250
).add_selection(selector)

points = base.mark_point(filled=True, size=200).encode(
x='mean(x)',
y='mean(y)',
color=alt.condition(selector, 'id:O', alt.value('lightgray'), legend=None),
).properties(
selection=selector,
width=250, height=250
).interactive()

timeseries = alt.Chart(data).mark_line().encode(
timeseries = base.mark_line().encode(
x='time',
y=alt.Y('value', scale=alt.Scale(domain=(-15, 15))),
color=alt.Color('id:O', legend=None)
).transform_filter(
selector
).properties(
selection=selector,
width=250, height=250
)

points | timeseries
Loading

0 comments on commit 143ad04

Please sign in to comment.