diff --git a/altair/vega/v2/display.py b/altair/vega/v2/display.py index cadc7756b..dd8027461 100644 --- a/altair/vega/v2/display.py +++ b/altair/vega/v2/display.py @@ -29,7 +29,7 @@ If you see this message, it means the renderer has not been properly enabled for the frontend that you are using. For more information, see -https://altair-viz.github.io/user_guide/renderers.html +https://altair-viz.github.io/user_guide/troubleshooting.html """ renderers = PluginRegistry[RendererType](entry_point_group=ENTRY_POINT_GROUP) diff --git a/altair/vega/v3/display.py b/altair/vega/v3/display.py index 4c836471b..fe758be01 100644 --- a/altair/vega/v3/display.py +++ b/altair/vega/v3/display.py @@ -29,7 +29,7 @@ If you see this message, it means the renderer has not been properly enabled for the frontend that you are using. For more information, see -https://altair-viz.github.io/user_guide/renderers.html +https://altair-viz.github.io/user_guide/troubleshooting.html """ renderers = PluginRegistry[RendererType](entry_point_group=ENTRY_POINT_GROUP) diff --git a/altair/vegalite/v1/display.py b/altair/vegalite/v1/display.py index e0ef3b852..251b6bfb4 100644 --- a/altair/vegalite/v1/display.py +++ b/altair/vegalite/v1/display.py @@ -34,7 +34,7 @@ If you see this message, it means the renderer has not been properly enabled for the frontend that you are using. For more information, see -https://altair-viz.github.io/user_guide/renderers.html +https://altair-viz.github.io/user_guide/troubleshooting.html """ renderers = PluginRegistry[RendererType](entry_point_group=ENTRY_POINT_GROUP) diff --git a/altair/vegalite/v2/display.py b/altair/vegalite/v2/display.py index 5cb333280..dba62be85 100644 --- a/altair/vegalite/v2/display.py +++ b/altair/vegalite/v2/display.py @@ -34,7 +34,7 @@ If you see this message, it means the renderer has not been properly enabled for the frontend that you are using. For more information, see -https://altair-viz.github.io/user_guide/renderers.html +https://altair-viz.github.io/user_guide/troubleshooting.html """ renderers = PluginRegistry[RendererType](entry_point_group=ENTRY_POINT_GROUP) diff --git a/doc/getting_started/installation.rst b/doc/getting_started/installation.rst index df99f0d11..68ea3b3cb 100644 --- a/doc/getting_started/installation.rst +++ b/doc/getting_started/installation.rst @@ -23,7 +23,7 @@ Quick Start: Altair + JupyterLab We recommend installing Altair with JupyterLab. If you would like to use it with the classic notebook, see :ref:`installation-notebook`. -To install Altair with pip, run the following commands:: +To install JupyterLab and Altair with pip, run the following commands:: $ pip install jupyterlab altair $ jupyter labextension install @jupyterlab/vega3-extension # not needed for JupyterLab 0.32 or newer @@ -32,7 +32,9 @@ Once this is finished, run:: $ jupyter lab -In the browser window that launches, under "Notebook" click "Python 3". +In the browser window that launches, under "Notebook" click the first available +kernel (it should say "Python 2" or "Python 3" depending on which Python version +you are running). In the notebook that opens, you can run the following code to ensure everything is properly set up: @@ -52,7 +54,7 @@ is properly set up: If the plot does not render, ensure you have installed the exact versions mentioned above, and if it still does not work see -:ref:`display-troubleshooting` for help. +:ref:`troubleshooting-jupyterlab` for help. Once things are up and running, you may wish to go through the tutorials at :ref:`starting` and :ref:`exploring-weather`, read through the User Guide @@ -75,7 +77,9 @@ Once the packages and extensions are installed, launch the notebook by running:: $ jupyter notebook In the browser window that launches, click the *New* drop-down menu and -select "Python 3".under "Notebook" click "Python 3". +select either "Python 2" or "Python 3", depending on which version of Python +you are using (note that the kernel you choose *must* match the kernel where +you installed the vega3 extension). In the notebook that opens, you can run the following code to ensure everything is properly set up: @@ -96,10 +100,6 @@ is properly set up: color='species' ) -If the plot does not render, ensure you have installed the exact versions -mentioned above, and if it still does not work see -:ref:`display-troubleshooting` for help. - .. note:: For the classic Jupyter notebook (not JupyterLab), each time you launch a @@ -110,6 +110,10 @@ mentioned above, and if it still does not work see If you neglect this step, charts will not be rendered, but instead displayed as a textual representation. +If the plot does not render, ensure you have installed the exact versions +mentioned above, and if it still does not work see +:ref:`troubleshooting-notebook` for help. + Once things are up and running, you may wish to go through the tutorials at :ref:`starting` and :ref:`exploring-weather`, read through the User Guide indexed in the left panel, or check out the :ref:`example-gallery` for more ideas. @@ -126,7 +130,7 @@ following in a notebook cell: # for colab only run this command once per session alt.renderers.enable('colab') -With this set up, paste the following code to check if renderings are working +Once you have run this, paste the following code to check if renderings are working correctly: .. altair-plot:: @@ -167,7 +171,7 @@ Dependencies Altair has the following dependencies, all of which are installed automatically with the above installation commands: -- python 2.7 or 3.5 or higher +- python 2.7, 3.5 or newer - entrypoints_ - IPython_ - jsonschema_ diff --git a/doc/index.rst b/doc/index.rst index a6a352c6e..72293891d 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -7,7 +7,8 @@ Altair: Declarative Visualization in Python :seed: 31415 Altair is a declarative statistical visualization library for Python, based on -Vega_ and Vega-Lite_. +Vega_ and Vega-Lite_, and the source is available on +`GitHub `_. With Altair, you can spend more time understanding your data and its meaning. Altair's API is simple, friendly and consistent and built on top of the @@ -56,7 +57,9 @@ beautiful and effective visualizations with a minimal amount of code. :caption: Advanced Usage user_guide/importing - user_guide/display + user_guide/display_frontends + user_guide/custom_renderers + user_guide/data_transformers Bug Reports & Questions ----------------------- diff --git a/doc/user_guide/compound_charts.rst b/doc/user_guide/compound_charts.rst index 2cac33e08..e0d1003d2 100644 --- a/doc/user_guide/compound_charts.rst +++ b/doc/user_guide/compound_charts.rst @@ -198,8 +198,8 @@ In this example, we explicitly loop over different x and y encodings to create a 2 x 2 grid of charts showing different views of the data. The code is straightforward, if a bit verbose. -The :class:`RepeatChart` pattern makes this type of chart a bit easier -to produce: +The :class:`RepeatChart` pattern, accessible via the :meth:`Chart.repeat` +method, makes this type of chart a bit easier to produce: .. altair-plot:: @@ -324,6 +324,10 @@ layered chart with a hover selection: data=iris ) +Notice that we specify the data within the facet here; this is important, because +the top-level facet needs access to this data in order to know how to encode +the column. + Though each of the above examples have faceted the data across columns, faceting across rows (or across rows *and* columns) is supported as well. diff --git a/doc/user_guide/custom_renderers.rst b/doc/user_guide/custom_renderers.rst new file mode 100644 index 000000000..0cebdede2 --- /dev/null +++ b/doc/user_guide/custom_renderers.rst @@ -0,0 +1,62 @@ + +.. _customizing-renderers: + +Customizing Renderers +===================== +Renderers in Altair are all based on the mimebundle representation accessed by +the ``_repr_mimebundle_`` method of the top-level Altair objects. When you enable +a renderer, functionally what that does is to define a new kind of mimebundle +output. + +The ``alt.renderers`` registry allows the user to define and enable new mimetypes +for the chart. +As a simple example, imagine we would like to add a ``plaintext`` renderer that +renders a chart description in plain text. We could do it this way:: + + def plaintext_mimetype(spec): + return {'text/plain': "description: " + spec.get('description', 'none')} + + alt.renderers.register('plaintext', plaintext_mimetype) + +Now you can enable this mimetype, and then when your chart is displayed you +will see this description:: + + alt.renderers.enable('plaintext') + + alt.Chart('data.txt').mark_point().encode( + x='x:Q', + y='y:Q' + ).properties( + description='This is a simple chart' + ) + +.. code-block:: none + + This is a simple chart + +This is a simple example, but it shows you the flexibility of this approach. +If you have a frontend that recognizes ``_repr_mimebundle_`` as a means of +obtaining a MIME type representation of a Python object, then you can define +a function that will process the chart content in any way before returning +any mimetype. + +The renderers built-in to Altair are the following: + +- ``"default"``: default rendering, using the + ``'application/vnd.vegalite.v2+json'`` MIME type which is supported + by JupyterLab and nteract. +- ``"jupyterlab"``: identical to ``"default"`` +- ``"nteract"``: identical to ``"default"`` +- ``"colab"``: renderer for Google's Colab notebook, using the + ``"text/html"`` MIME type. +- ``"notebook"``: renderer for the classic notebook, provided by the ipyvega3_ + package +- ``"json"``: renderer that outputs the raw JSON chart specification, using the + ``'application/json'`` MIME type. +- ``"png"``: renderer that renders and converts the chart to PNG, outputting it + using the ``'image/png'`` MIME type. +- ``"svg"``: renderer that renders and converts the chart to an SVG image, + outputting it using the ``'image/svg+xml'`` MIME type. + + +.. _ipyvega3: https://github.com/vega/ipyvega/tree/vega3 diff --git a/doc/user_guide/data_transformers.rst b/doc/user_guide/data_transformers.rst new file mode 100644 index 000000000..12297d335 --- /dev/null +++ b/doc/user_guide/data_transformers.rst @@ -0,0 +1,106 @@ +.. _data-transformers: + +Data transformers +================= + +Before a Vega-Lite or Vega specification can be passed to a renderer, it typically +has to be transformed in a number of ways: + +* Pandas Dataframe has to be sanitized and serialized to JSON. +* The rows of a Dataframe might need to be sampled or limited to a maximum number. +* The Dataframe might be written to a ``.csv`` of ``.json`` file for performance + reasons. + +These data transformations are managed by the data transformation API of Altair. + +.. note:: + + The data transformation API of Altair should not be confused with the ``transform`` + API of Vega and Vega-Lite. + +A data transformer is a Python function that takes a Vega-Lite data ``dict`` or +Pandas ``DataFrame`` and returns a transformed version of either of these types:: + + from typing import Union + Data = Union[dict, pd.DataFrame] + + def data_transformer(data: Data) -> Data: + # Transform and return the data + return transformed_data + +Built-in data transformers +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Altair includes a default set of data transformers with the following signatures. + +Raise a ``MaxRowsError`` if a Dataframe has more than ``max_rows`` rows:: + + limit_rows(data, max_rows=5000) + +Randomly sample a DataFrame (without replacement) before visualizing:: + + sample(data, n=None, frac=None) + +Convert a Dataframe to a separate ``.json`` file before visualization:: + + to_json(data, prefix='altair-data'): + +Convert a Dataframe to a separate ``.csv`` file before visualiztion:: + + to_csv(data, prefix='altair-data'): + +Convert a Dataframe to inline JSON values before visualization:: + + to_values(data): + +Piping +~~~~~~ + +Multiple data transformers can be piped together using ``pipe``:: + + from altair import pipe, limit_rows, to_values + pipe(data, limit_rows(10000), to_values) + +Managing data transformers +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Altair maintains a registry of data transformers, which includes a default +data transformer that is automatically applied to all Dataframes before rendering. + +To see the registered transformers:: + + >>> import altair as alt + >>> alt.data_transformers.names() + ['default', 'json', 'csv'] + +The default data transformer is the following:: + + def default_data_transformer(data): + return pipe(data, limit_rows, to_values) + +The ``json`` and ``csv`` data transformers will save a Dataframe to a temporary +``.json`` or ``.csv`` file before rendering. There are a number of performance +advantages to these two data transformers: + +* The full dataset will not be saved in the notebook document. +* The performance of the Vega-Lite/Vega JavaScript appears to be better + for standalone JSON/CSV files than for inline values. + +There are disadvantages of the JSON/CSV data transformers: + +* The Dataframe will be exported to a temporary ``.json`` or ``.csv`` + file that sits next to the notebook. +* That notebook will not be able to re-render the visualization without + that temporary file (or re-running the cell). + +In our experience, the performance improvement is significant enough that +we recommend using the ``json`` data transformer for any large datasets:: + + alt.data_transformers.enable('json') + +We hope that others will write additional data transformers - imagine a +transformer which saves the dataset to a JSON file on S3, which could +be registered and enabled as:: + + alt.data_transformers.register('s3', lambda data: pipe(sample, to_s3('mybucket'))) + alt.data_transformers.enable('s3') diff --git a/doc/user_guide/display.rst b/doc/user_guide/display_frontends.rst similarity index 68% rename from doc/user_guide/display.rst rename to doc/user_guide/display_frontends.rst index 11fa9b849..de02ea10e 100644 --- a/doc/user_guide/display.rst +++ b/doc/user_guide/display_frontends.rst @@ -1,7 +1,7 @@ .. _displaying-charts: -Displaying Charts -================= +Displaying Charts in Various Frontends +====================================== Altair provides a high-level API for creating visualizations that are encoded as declarative JSON objects. To display a visualization, those JSON @@ -56,6 +56,7 @@ Altair displays visualizations using renderers. There are two aspects of rendere * :ref:`display-notebook` * :ref:`display-jupyterlab` * :ref:`display-nteract` + * :ref:`display-colab` .. _renderer-api: @@ -225,114 +226,6 @@ At the top of your Colab session, run the following:: And then you can create Altair plots normally within the notebook. -.. _data-transformers: - -Data transformers ------------------ - -Before a Vega-Lite or Vega specification can be passed to a renderer, it typically -has to be transformed in a number of ways: - -* Pandas Dataframe has to be sanitized and serialized to JSON. -* The rows of a Dataframe might need to be sampled or limited to a maximum number. -* The Dataframe might be written to a ``.csv`` of ``.json`` file for performance - reasons. - -These data transformations are managed by the data transformation API of Altair. - -.. note:: - - The data transformation API of Altair should not be confused with the ``transform`` - API of Vega and Vega-Lite. - -A data transformer is a Python function that takes a Vega-Lite data ``dict`` or -Pandas ``DataFrame`` and returns a transformed version of either of these types:: - - from typing import Union - Data = Union[dict, pd.DataFrame] - - def data_transformer(data: Data) -> Data: - # Transform and return the data - return transformed_data - -Built-in data transformers -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Altair includes a default set of data transformers with the following signatures. - -Raise a ``MaxRowsError`` if a Dataframe has more than ``max_rows`` rows:: - - limit_rows(data, max_rows=5000) - -Randomly sample a DataFrame (without replacement) before visualizing:: - - sample(data, n=None, frac=None) - -Convert a Dataframe to a separate ``.json`` file before visualization:: - - to_json(data, prefix='altair-data'): - -Convert a Dataframe to a separate ``.csv`` file before visualiztion:: - - to_csv(data, prefix='altair-data'): - -Convert a Dataframe to inline JSON values before visualization:: - - to_values(data): - -Piping -~~~~~~ - -Multiple data transformers can be piped together using ``pipe``:: - - from altair import pipe, limit_rows, to_values - pipe(data, limit_rows(10000), to_values) - -Managing data transformers -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Altair maintains a registry of data transformers, which includes a default -data transformer that is automatically applied to all Dataframes before rendering. - -To see the registered transformers:: - - >>> import altair as alt - >>> alt.data_transformers.names() - ['default', 'json', 'csv'] - -The default data transformer is the following:: - - def default_data_transformer(data): - return pipe(data, limit_rows, to_values) - -The ``json`` and ``csv`` data transformers will save a Dataframe to a temporary -``.json`` or ``.csv`` file before rendering. There are a number of performance -advantages to these two data transformers: - -* The full dataset will not be saved in the notebook document. -* The performance of the Vega-Lite/Vega JavaScript appears to be better - for standalone JSON/CSV files than for inline values. - -There are disadvantages of the JSON/CSV data transformers: - -* The Dataframe will be exported to a temporary ``.json`` or ``.csv`` - file that sits next to the notebook. -* That notebook will not be able to re-render the visualization without - that temporary file (or re-running the cell). - -In our experience, the performance improvement is significant enough that -we recommend using the ``json`` data transformer for any large datasets:: - - alt.data_transformers.enable('json') - -We hope that others will write additional data transformers - imagine a -transformer which saves the dataset to a JSON file on S3, which could -be registered and enabled as:: - - alt.data_transformers.register('s3', lambda data: pipe(sample, to_s3('mybucket'))) - alt.data_transformers.enable('s3') - - .. _entrypoints: https://github.com/takluyver/entrypoints .. _ipyvega: https://github.com/vega/ipyvega/tree/master diff --git a/doc/user_guide/importing.rst b/doc/user_guide/importing.rst index fadaac9dc..01eb7e8ca 100644 --- a/doc/user_guide/importing.rst +++ b/doc/user_guide/importing.rst @@ -1,45 +1,36 @@ .. _importing: -Importing Altair -================ +Importing Vega & Vega-Lite Versions +=================================== -As of Altair 2.0, we include support for multiple versions of both -Vega-Lite (1.x and 2.x) and Vega (2.x and 3.x) in a single Python package. -This section of the documentation describes how you can import the different -versions of the Python APIs. +The main Altair API is based on version 2.X of `Vega-Lite`_. The core of the API, +found in the ``altair.vegalite.v2.schema`` module, is programmatically generated +from the Vega-Lite schema. -.. note:: - - We strongly recommend all users transition to Vega-Lite 2.x and Vega 3.x. - These versions support many new features, are more stable, and Altair 2.0 - works best with them. - -Vega-Lite ---------- - -To import the latest version of the Python API for Vega-Lite:: +Altair additionally provides wrappers for several other schemas: - import altair as alt +- Vega-Lite 1.X in ``altair.vegalite.v1`` +- Vega 2.X in ``altair.vega.v2`` +- Vega 3.X in ``altair.vega.v3`` -**This is the Python API recommended for most users.** +So, for example, if you would like to create Altair plots targeting Vega-Lite +version 1, you can use:: -Currently, this points to the Vega-Lite 2.x API, which can be imported -explicitly as:: + import altair.vegalite.v1 as alt - import altair.vegalite.v2 as alt +and then proceed to use the Altair version 1 API. -The older, Vega-Lite 1.x Python API is available as:: - - import altair.vegalite.v1 as alt - -Vega ----- - -To import the Python API for Vega 3.x, use:: +.. note:: - import altair.vega.v3 as vega + We strongly recommend all users transition to Vega-Lite 2.x and Vega 3.x. + These versions support many new features, are more stable, and Altair 2.0 + works best with them. -To import the Python API for Vega 2.x, use:: +Because Altair has focused primarily on the vega-lite API, the vega wrappers are +far less developed than the vega-lite wrappers, though it is possible to +create Vega plots using a very low-level Python interface that mirrors the +schema itself. - import altair.vega.v2 as vega +.. Vega-Lite: http://vega.github.io/vega-lite/ +.. Vega: http://vega.github.io/vega/ diff --git a/doc/user_guide/marks.rst b/doc/user_guide/marks.rst index 9017b5cad..e2528e34e 100644 --- a/doc/user_guide/marks.rst +++ b/doc/user_guide/marks.rst @@ -49,3 +49,11 @@ arguments to represent points as red semi-transparent filled circles: x='Horsepower:Q', y='Miles_per_Gallon:Q' ) + +The additional arguments to ``mark_*()`` methods are passed along to an +associated :class:`MarkDef` instance, which supports the following attributes: + +.. altair-object-table:: altair.MarkDef + +Marks can also be configured globally using chart-level configurations; see +:ref:`config-mark` for details. diff --git a/doc/user_guide/saving_charts.rst b/doc/user_guide/saving_charts.rst index c63feddd7..308530a6f 100644 --- a/doc/user_guide/saving_charts.rst +++ b/doc/user_guide/saving_charts.rst @@ -37,10 +37,10 @@ Firefox, which requires the following: Chrome or Firefox installation page for installation details for your own operating system. -- `Chrome Driver`_ or `Gecko Driver`_, which allows Chrome or Firefox to be run - in a *headless* state (i.e. to execute Javascript code without opening an - actual browser window). If you use homebrew on OSX, this can be installed - with:: +- `Chrome Driver`_ or `Gecko Driver`_, which allows Chrome or Firefox + respectively to be run in a *headless* state (i.e. to execute Javascript + code without opening an actual browser window). + If you use homebrew on OSX, this can be installed with:: $ brew install chromedriver $ brew install geckodriver @@ -74,7 +74,7 @@ For example, here we save a simple scatter-plot to JSON: chart.save('chart.json') -The condetns of the resulting file will look something like this: +The contetns of the resulting file will look something like this: .. code-block:: json diff --git a/doc/user_guide/transform.rst b/doc/user_guide/transform.rst index 36f4ff8a9..f7a7b7b4e 100644 --- a/doc/user_guide/transform.rst +++ b/doc/user_guide/transform.rst @@ -70,15 +70,15 @@ grouped by the number of Cylinders. The Altair shorthand string:: - ... + # ... y='mean(acceleration):Q', - ... + # ... is made available for convenience, and is equivalent to the longer form:: - ... - y=alt.Y(field='acceleration', aggregate='mean', type='quantitative') - ... + # ... + y=alt.Y(field='acceleration', aggregate='mean', type='quantitative'), + # ... For more information on shorthand encodings specifications, see :ref:`encoding-aggregates`. diff --git a/doc/user_guide/troubleshooting.rst b/doc/user_guide/troubleshooting.rst index c24daf6c4..dae21fa32 100644 --- a/doc/user_guide/troubleshooting.rst +++ b/doc/user_guide/troubleshooting.rst @@ -1,4 +1,4 @@ -.. _display-troubleshooting +.. _display-troubleshooting: Display Troubleshooting ======================= @@ -9,17 +9,17 @@ into strange states where things don't immediately work as expected. This section summarizes some of the most common problems and their solutions. -.. _trouble-shooting-jupyterlab +.. _troubleshooting-jupyterlab: Trouble-shooting Altair with JupyterLab --------------------------------------- -.. _jupyterlab-vega-lite-2-object +.. _jupyterlab-vega-lite-2-object: -VegaLite 2 Object -~~~~~~~~~~~~~~~~~ -**If you are using the Jupyter notebook rather than JupyterLab, see -:ref:`notebook-vega-lite-2-object` for information on this error** +JupyterLab: VegaLite 2 Object +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*If you are using the Jupyter notebook rather than JupyterLab, then refer to* +:ref:`notebook-vega-lite-2-object` If you are using JupyterLab (not Jupyter notebook) and see the following output:: @@ -87,17 +87,17 @@ it can mean one of two things is wrong is only necessary if you've somewhere changed the renderer explicitly). -.. _trouble-shooting-jupyterlab +.. _troubleshooting-notebook: Trouble-shooting Altair with Notebook ------------------------------------- -.. _notebook-vega-lite-2-object +.. _notebook-vega-lite-2-object: -VegaLite 2 object -~~~~~~~~~~~~~~~~~ -**If you are using JupyterLab rather than the Jupyter notebook, see -:ref:`jupyterlab-vega-lite-2-object` for information on this error** +Notebook: VegaLite 2 object +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*If you are using JupyterLab rather than the Jupyter notebook, then refer to* +:ref:`jupyterlab-vega-lite-2-object` If you are using the notebook (not JupyterLab) and see the the following output:: @@ -110,8 +110,9 @@ Jupyter extension, and then enable it using:: import altair as alt alt.renderers.enable('notebook') -in order to render charts in the classic notebook. If the above code gives an -error:: +in order to render charts in the classic notebook. + +If the above code gives an error:: NoSuchEntryPoint: No 'notebook' entry point found in group 'altair.vegalite.v2.renderer' @@ -119,7 +120,11 @@ This means that you have not installed the vega3 package. If you see this error, please make sure to follow the standard installation instructions at :ref:`installation-notebook`. -.. _trouble-shooting-general +If you have done the above steps and charts still do not render, it likely means +that you are using a different *Kernel* within your notebook. Switch to the kernel +named *Python 2* if you are using Python 2, or *Python 3* if you are using Python 3. + +.. _troubleshooting-general: General Trouble-shooting ------------------------ @@ -204,7 +209,7 @@ an evaluation of that variable: chart -Alternatively, you can construct a chart directly, and not assign it to a varaible, +Alternatively, you can evaluate a chart directly, and not assign it to a variable, in which case the object definition itself is the final statement and will be displayed as an output: