Repository: vega/altair

Issue:
chart.serve() ignores data transformers
```python
import altair as alt

alt.data_transformers.enable('data_server')

from vega_datasets import data
cars = data.cars()

chart = alt.Chart(cars).mark_point().encode(
    x='Horsepower',
    y='Miles_per_Gallon',
    color='Origin',
).interactive()

chart.serve()
```
Examining the HTML from the above chart, we see that the data is not transformed.



Discussion:
Turns out we need
```python
chart.serve(override_data_transformer=False)
```
This default option is meant to disable ``MaxRowsError`` in the common case... perhaps there's a less obtrusive way to do that?
I think given the intent of the keyword, we should introduce something like ``alt.data_transformers.set_max_rows(None)`` and use that function instead.

Resolving patch:
diff --git a/altair/vegalite/data.py b/altair/vegalite/data.py
--- a/altair/vegalite/data.py
+++ b/altair/vegalite/data.py
@@ -3,8 +3,9 @@
 from ..utils.core import sanitize_dataframe
 from ..utils.data import (
     MaxRowsError, limit_rows, sample, to_csv, to_json, to_values,
-    check_data_type, DataTransformerRegistry
+    check_data_type
 )
+from ..utils.data import DataTransformerRegistry as _DataTransformerRegistry
 
 
 @curry
@@ -12,6 +13,16 @@ def default_data_transformer(data, max_rows=5000):
     return pipe(data, limit_rows(max_rows=max_rows), to_values)
 
 
+class DataTransformerRegistry(_DataTransformerRegistry):
+    def disable_max_rows(self):
+        """Disable the MaxRowsError."""
+        options = self.options
+        if self.active == 'default':
+            options = options.copy()
+            options['max_rows'] = None
+        return self.enable(**options)
+
+
 __all__ = (
     'DataTransformerRegistry',
     'MaxRowsError',
diff --git a/altair/vegalite/v3/api.py b/altair/vegalite/v3/api.py
--- a/altair/vegalite/v3/api.py
+++ b/altair/vegalite/v3/api.py
@@ -445,9 +445,9 @@ def save(self, fp, format=None, override_data_transformer=True,
             the format to write: one of ['json', 'html', 'png', 'svg'].
             If not specified, the format will be determined from the filename.
         override_data_transformer : boolean (optional)
-            If True (default), then the save action will be done with the
-            default data_transformer with max_rows set to None. If False,
-            then use the currently active data transformer.
+            If True (default), then the save action will be done with
+            the MaxRowsError disabled. If False, then do not change the data
+            transformer.
         scale_factor : float
             For svg or png formats, scale the image by this factor when saving.
             This can be used to control the size or resolution of the output.
@@ -470,7 +470,7 @@ def save(self, fp, format=None, override_data_transformer=True,
         # that save() will succeed even for large datasets that would
         # normally trigger a MaxRowsError
         if override_data_transformer:
-            with data_transformers.enable('default', max_rows=None):
+            with data_transformers.disable_max_rows():
                 result = save(**kwds)
         else:
             result = save(**kwds)


Test patch:
diff --git a/altair/vegalite/v2/tests/test_data.py b/altair/vegalite/v2/tests/test_data.py
new file mode 100644
--- /dev/null
+++ b/altair/vegalite/v2/tests/test_data.py
@@ -0,0 +1,33 @@
+import os
+
+import pandas as pd
+import pytest
+
+from .. import data as alt
+
+
+@pytest.fixture
+def sample_data():
+    return pd.DataFrame({'x': range(10), 'y': range(10)})
+
+
+def test_disable_max_rows(sample_data):
+    with alt.data_transformers.enable('default', max_rows=5):
+        # Ensure max rows error is raised.
+        with pytest.raises(alt.MaxRowsError):
+            alt.data_transformers.get()(sample_data)
+
+        # Ensure that max rows error is properly disabled.
+        with alt.data_transformers.disable_max_rows():
+            alt.data_transformers.get()(sample_data)
+
+    try:
+        with alt.data_transformers.enable('json'):
+            # Ensure that there is no TypeError for non-max_rows transformers.
+            with alt.data_transformers.disable_max_rows():
+                jsonfile = alt.data_transformers.get()(sample_data)
+    except:
+        jsonfile = {}
+    finally:
+        if jsonfile:
+            os.remove(jsonfile['url'])
\ No newline at end of file
diff --git a/altair/vegalite/v3/tests/test_data.py b/altair/vegalite/v3/tests/test_data.py
new file mode 100644
--- /dev/null
+++ b/altair/vegalite/v3/tests/test_data.py
@@ -0,0 +1,33 @@
+import os
+
+import pandas as pd
+import pytest
+
+from .. import data as alt
+
+
+@pytest.fixture
+def sample_data():
+    return pd.DataFrame({'x': range(10), 'y': range(10)})
+
+
+def test_disable_max_rows(sample_data):
+    with alt.data_transformers.enable('default', max_rows=5):
+        # Ensure max rows error is raised.
+        with pytest.raises(alt.MaxRowsError):
+            alt.data_transformers.get()(sample_data)
+
+        # Ensure that max rows error is properly disabled.
+        with alt.data_transformers.disable_max_rows():
+            alt.data_transformers.get()(sample_data)
+
+    try:
+        with alt.data_transformers.enable('json'):
+            # Ensure that there is no TypeError for non-max_rows transformers.
+            with alt.data_transformers.disable_max_rows():
+                jsonfile = alt.data_transformers.get()(sample_data)
+    except:
+        jsonfile = {}
+    finally:
+        if jsonfile:
+            os.remove(jsonfile['url'])
\ No newline at end of file