diff --git a/altair/vegalite/v2/api.py b/altair/vegalite/v2/api.py
index f0bf2a67..dc8f10a7 100644
--- a/altair/vegalite/v2/api.py
+++ b/altair/vegalite/v2/api.py
@@ -17,18 +17,50 @@ from .theme import themes
 
 # ------------------------------------------------------------------------
 # Data Utilities
-def _dataset_name(data):
-    """Generate a unique hash of the data"""
-    def hash_(dct):
-        dct_str = json.dumps(dct, sort_keys=True)
-        return hashlib.md5(dct_str.encode()).hexdigest()
+def _dataset_name(values):
+    """Generate a unique hash of the data
+
+    Parameters
+    ----------
+    values : list or dict
+        A list/dict representation of data values.
+
+    Returns
+    -------
+    name : string
+        A unique name generated from the hash of the values.
+    """
+    if isinstance(values, core.InlineDataset):
+        values = values.to_dict()
+    values_json = json.dumps(values, sort_keys=True)
+    hsh = hashlib.md5(values_json.encode()).hexdigest()
+    return 'data-' + hsh
+
+
+def _consolidate_data(data, context):
+    """If data is specified inline, then move it to context['datasets']
+
+    This function will modify context in-place, and return a new version of data
+    """
+    values = Undefined
+    kwds = {}
 
     if isinstance(data, core.InlineData):
-        return 'data-' + hash_(data.values)
-    elif isinstance(data, dict) and 'values' in data:
-        return 'data-' + hash_(data['values'])
-    else:
-        raise ValueError("Cannot generate name for data {0}".format(data))
+        if data.name is Undefined and data.values is not Undefined:
+            values = data.values
+            kwds = {'format': data.format}
+
+    elif isinstance(data, dict):
+        if 'name' not in data and 'values' in data:
+            values = data['values']
+            kwds = {k:v for k,v in data.items() if k != 'values'}
+
+    if values is not Undefined:
+        name = _dataset_name(values)
+        data = core.NamedData(name=name, **kwds)
+        context.setdefault('datasets', {})[name] = values
+
+    return data
 
 
 def _prepare_data(data, context):
@@ -46,35 +78,25 @@ def _prepare_data(data, context):
     """
     if data is Undefined:
         return data
-    if isinstance(data, core.InlineData):
-        if data_transformers.consolidate_datasets:
-            name = _dataset_name(data)
-            context.setdefault('datasets', {})[name] = data.values
-            return core.NamedData(name=name)
-        else:
-            return data
-    elif isinstance(data, dict) and 'values' in data:
-        if data_transformers.consolidate_datasets:
-            name = _dataset_name(data)
-            context.setdefault('datasets', {})[name] = data['values']
-            return core.NamedData(name=name)
-        else:
-            return data
-    elif isinstance(data, pd.DataFrame):
+
+    # convert dataframes to dict
+    if isinstance(data, pd.DataFrame):
         data = pipe(data, data_transformers.get())
-        if data_transformers.consolidate_datasets and isinstance(data, dict) and 'values' in data:
-            name = _dataset_name(data)
-            context.setdefault('datasets', {})[name] = data['values']
-            return core.NamedData(name=name)
-        else:
-            return data
-    elif isinstance(data, (dict, core.Data, core.UrlData, core.NamedData)):
-        return data
-    elif isinstance(data, six.string_types):
-        return core.UrlData(data)
-    else:
+
+    # convert string input to a URLData
+    if isinstance(data, six.string_types):
+        data = core.UrlData(data)
+
+    # consolidate inline data to top-level datasets
+    if data_transformers.consolidate_datasets:
+        data = _consolidate_data(data, context)
+
+    # if data is still not a recognized type, then return
+    if not isinstance(data, (dict, core.Data, core.UrlData,
+                             core.InlineData, core.NamedData)):
         warnings.warn("data of type {0} not recognized".format(type(data)))
-        return data
+
+    return data
 
 
 # ------------------------------------------------------------------------

Altair 2.2 losses format property of InlineData object
~~~python
data = alt.InlineData(
    values={'a':[{'b': 0}, {'b': 1}, {'b': 2}]},
    format=alt.DataFormat(
            type='json',
            property='a',
    ))
chart = alt.Chart(
            data
       ).mark_tick(
       ).encode(
            x='b:N'
       )

chart
~~~
![visualization 36](https://user-images.githubusercontent.com/11561581/44123732-63aeb738-a032-11e8-9ee2-d3ced575296d.png)

**but**
~~~python 
alt.data_transformers.enable(consolidate_datasets=False)
chart

~~~
![visualization 37](https://user-images.githubusercontent.com/11561581/44123818-b9c2fefe-a032-11e8-91a8-53a262ef8989.png)
diff --git a/altair/vegalite/v2/tests/test_api.py b/altair/vegalite/v2/tests/test_api.py
index aeba0701..dbb101eb 100644
--- a/altair/vegalite/v2/tests/test_api.py
+++ b/altair/vegalite/v2/tests/test_api.py
@@ -460,3 +460,35 @@ def test_consolidate_datasets(basic_chart):
 
     for spec in dct_consolidated['hconcat']:
         assert spec['data'] == {'name': name}
+
+
+def test_consolidate_InlineData():
+    data = alt.InlineData(
+        values=[{'a': 1, 'b': 1}, {'a': 2, 'b': 2}],
+        format={'type': 'csv'}
+    )
+    chart = alt.Chart(data).mark_point()
+
+    with alt.data_transformers.enable(consolidate_datasets=False):
+        dct = chart.to_dict()
+    assert dct['data']['format'] == data.format
+    assert dct['data']['values'] == data.values
+
+    with alt.data_transformers.enable(consolidate_datasets=True):
+        dct = chart.to_dict()
+    assert dct['data']['format'] == data.format
+    assert list(dct['datasets'].values())[0] == data.values
+
+    data = alt.InlineData(
+        values=[],
+        name='runtime_data'
+    )
+    chart = alt.Chart(data).mark_point()
+
+    with alt.data_transformers.enable(consolidate_datasets=False):
+        dct = chart.to_dict()
+    assert dct['data'] == data.to_dict()
+
+    with alt.data_transformers.enable(consolidate_datasets=True):
+        dct = chart.to_dict()
+    assert dct['data'] == data.to_dict()

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
-e git+https://github.com/altair-viz/altair.git@2fbbb9ae469c4a8306462e0fcc81f8df57b29776#egg=altair
attrs==22.2.0
Babel==2.11.0
backcall==0.2.0
certifi==2021.5.30
charset-normalizer==2.0.12
commonmark==0.9.1
decorator==5.1.1
docutils==0.17.1
entrypoints==0.4
flake8==5.0.4
idna==3.10
imagesize==1.4.1
importlib-metadata==4.2.0
iniconfig==1.1.1
ipython==7.16.3
ipython-genutils==0.2.0
jedi==0.17.2
Jinja2==3.0.3
jsonschema==3.2.0
m2r==0.3.1
MarkupSafe==2.0.1
mccabe==0.7.0
mistune==0.8.4
numpy==1.19.5
packaging==21.3
pandas==1.1.5
parso==0.7.1
pexpect==4.9.0
pickleshare==0.7.5
pluggy==1.0.0
prompt-toolkit==3.0.36
ptyprocess==0.7.0
py==1.11.0
pycodestyle==2.9.1
pyflakes==2.5.0
Pygments==2.14.0
pyparsing==3.1.4
pyrsistent==0.18.0
pytest==7.0.1
python-dateutil==2.9.0.post0
pytz==2025.2
recommonmark==0.7.1
requests==2.27.1
six==1.17.0
snowballstemmer==2.2.0
Sphinx==4.3.2
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
tomli==1.2.3
toolz==0.12.0
traitlets==4.3.3
typing==3.7.4.3
typing_extensions==4.1.1
urllib3==1.26.20
vega-datasets==0.9.0
wcwidth==0.2.13
zipp==3.6.0

name: altair
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - attrs==22.2.0
      - babel==2.11.0
      - backcall==0.2.0
      - charset-normalizer==2.0.12
      - commonmark==0.9.1
      - decorator==5.1.1
      - docutils==0.17.1
      - entrypoints==0.4
      - flake8==5.0.4
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.2.0
      - iniconfig==1.1.1
      - ipython==7.16.3
      - ipython-genutils==0.2.0
      - jedi==0.17.2
      - jinja2==3.0.3
      - jsonschema==3.2.0
      - m2r==0.3.1
      - markupsafe==2.0.1
      - mccabe==0.7.0
      - mistune==0.8.4
      - numpy==1.19.5
      - packaging==21.3
      - pandas==1.1.5
      - parso==0.7.1
      - pexpect==4.9.0
      - pickleshare==0.7.5
      - pluggy==1.0.0
      - prompt-toolkit==3.0.36
      - ptyprocess==0.7.0
      - py==1.11.0
      - pycodestyle==2.9.1
      - pyflakes==2.5.0
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pyrsistent==0.18.0
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - recommonmark==0.7.1
      - requests==2.27.1
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==4.3.2
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - tomli==1.2.3
      - toolz==0.12.0
      - traitlets==4.3.3
      - typing==3.7.4.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - vega-datasets==0.9.0
      - wcwidth==0.2.13
      - zipp==3.6.0
prefix: /opt/conda/envs/altair

altair/vegalite/v2/tests/test_api.py::test_consolidate_InlineData
altair/vegalite/v2/tests/test_api.py::test_chart_data_types altair/vegalite/v2/tests/test_api.py::test_chart_infer_types altair/vegalite/v2/tests/test_api.py::test_facet_parse_data altair/vegalite/v2/tests/test_api.py::test_LookupData altair/vegalite/v2/tests/test_api.py::test_consolidate_datasets
altair/vegalite/v2/tests/test_api.py::test_multiple_encodings altair/vegalite/v2/tests/test_api.py::test_chart_operations altair/vegalite/v2/tests/test_api.py::test_selection_to_dict altair/vegalite/v2/tests/test_api.py::test_facet_parse altair/vegalite/v2/tests/test_api.py::test_SelectionMapping altair/vegalite/v2/tests/test_api.py::test_transforms altair/vegalite/v2/tests/test_api.py::test_filter_transform_selection_predicates altair/vegalite/v2/tests/test_api.py::test_resolve_methods altair/vegalite/v2/tests/test_api.py::test_add_selection altair/vegalite/v2/tests/test_api.py::test_themes altair/vegalite/v2/tests/test_api.py::test_chart_from_dict
altair/vegalite/v2/api.py
altair/vegalite/v2/api.py