FAQ
===

Here is a list of questions we have either been asked by users or potential pitfalls we hope to help users avoid:


**Q: What objects can I use with Panel?**

**A:** The Panel `Component Gallery <https://panel.pyviz.org/reference/>`__ shows examples of all the plotting libraries, data types, image formats, and other objects that can be used in a panel.  There is also a older `Github issue <https://github.com/pyviz/panel/issues/2>`__ where possible types are discussed.


**Q: Does it matter which plotting library I use with Panel?**

**A:** Yes and no! Just about `any Python library <https://pyviz.org/tools.html>`__ will work with Panel. That said, only certain libraries will provide deeply interactive objects in a web browser, such as Bokeh and Plotly.  If you want to tie custom actions to individual sub-elements of such a plot, you should use a library with extensive JavaScript support. Otherwise, just use any supported library that you prefer!


**Q: How do I add support for a library or datatype not yet supported?**

**A:** It depends. If the object already has one of the usual IPython ``_repr_X_`` rich display methods (where X is png, jpg, svg, or html), then it is very likely to work already. Try it!  If it doesn't have a rich display method, check to see if you can add one as a PR to that project -- those representations are very useful for many cases other than Panel, too. Otherwise, adding support is quite easy for anything that can somehow return an image or some HTML. If it can return an image in any way, see the ``panel.pane.Matplotlib`` implementation as a starting point; you just need to be able to call some method or function on the object to return an image, and the rest should be simple.

If you want an even richer JavaScript-based representation where that's supported by a library but not yet by Panel, it will be more difficult to add that, but you can see the ``pane.Bokeh`` class and the ``panel.holoviews`` and ``panel.plotly`` modules for examples.


**Q: How does Panel compare to other dashboarding libraries?**

See the `technology comparisons section <https://panel.holoviz.org/explanation/index.html#technology-comparisons>`__ for a detailed comparison between Panel and other dashboarding/app libraries.


**Q: How does Panel relate to Bokeh?**

**A:** Panel is built on infrastructure provided by Bokeh, specifically Bokeh's model base classes, layouts, widgets, and (optionally) its server. But Panel does not require using any of Bokeh's plotting support. This way you can make use of a solid, well supported low-level toolkit (Bokeh) to build apps and dashboards for your own plots from any supported library.

Conversely, what Panel adds on top of Bokeh is full bidirectional communication between Python and JavaScript both in a Jupyter session (classic notebook or Jupyter Lab) and in a standalone Bokeh server, making it trivial to move code between Jupyter and server contexts. It then uses this two-way "comms" support to provide reactive widgets, containers, and views that make it simple to put together widget-controlled objects accessible from either Python or JavaScript. Finally, Panel adds a large set of wrappers for common plot and image types so that they can easily be laid out into small apps or full dashboards.


**Q: Why do I get an error "Javascript error adding output! TypeError: Cannot read property 'comm_manager' of undefined"?**

**A:** This error usually means that you forgot to run panel.extension() in a notebook context to set up the code for communicating between JavaScript and Python.  It's easy to get confused and think you don't need that line, because notebooks will often work fine as long as *some* notebook somewhere in your Jupyter session has run the command, but the only reliable way to make the communication channels available is to make sure *every* notebook includes this command.

**Q: How do I enable the panel widget on older versions of Jupyter Lab?**

**A:** Run `jupyter serverextension enable panel.io.jupyter_server_extension` (not needed in modern Jupyter Lab or Panel versions).

**Q: Why is my object being shown using the wrong type of pane?**

**A:** A global set of precedence values is used to ensure that the richest representation of a given object is chosen when you pass it to a Row or Column. For instance, if ``obj`` is "# Some text", it be displayed as a ``pn.Str``, ``pn.HTML``, or ``pn.Markdown``, all of which can render a Python string like that.  By default, something like ``pn.Row(obj)`` will select a Markdown pane for the obj, because Markdown has a higher precedence than the other options.  If you want to override the default pane type selected, you can specify the precise Pane type you wish, as in ``pn.Row(pane.Str("# Some text"))``, which also allows you to pass in options like ``pn.Row(pane.Str("# Some text", height=300))``.  If the default Pane type is fine but you still want to be able to pass specific options like width or height in this way, you can invoke the ``pn.panel`` function to create a defauot pane with the supplied arguments, as in  ``pn.Row(pn.panel(obj, height=300))``.


**Q: For Matplotlib plots in a notebook, why do I get no plot, two plots, or plots that fail to update?**

**A:** The Matplotlib pyplot interface behaves in a way that is not easily compatible with Panel in a notebook. Normal Python objects like Python literals and containers display when they are returned as a cell's value, but Matplotlib figures created using pyplot have a textual representation by default but then (depending on the Matplotlib backend and IPython configuration) also display like print statements do, i.e. with a plot as a side effect rather than as a representation of the return value. To force predictable Panel-compatible behavior we therefore recommend using the object-oriented API:

1. Create a figure object explicitly using ``from matplotlib.figure import Figure``
2. Return the figure in your callback.

As an example creating a simple plot might look like this::

    fig = Figure(figsize=(10, 6))
    ax = fig.subplots()
    ax.plot([1, 2, 3])
    pn.pane.Matplotlib(fig)

When using the pandas plotting API we create the figure and axes in the same way as before but then pass the axis to the plotting call::

    df = pd.DataFrame({"x": [1, 2, 3])
    df.plot(ax=ax)
    pn.pane.Matplotlib(fig)

**Q: How do I debug error messages in a notebook?**

**A**: When displaying a Panel object in a Jupyter notebook all errors and print output will be displayed at the top of the cell. This can be controlled using the `panel.config.console_output` option, which can be set to 'accumulate' (the default), 'replace' to replace the output each time and finally 'disable' which hides the output.

**Q: Does Panel require a live Python process for deployment, or can I export to a static HTML document to email or put on a web server?**

**A:** That depends. Panel supports dynamically executing Python code as a user interacts with a panel, for which Python must be running (either as a server process or in the client using WASM).  But panels can be exported to static HTML, with all functionality that relies only on JavaScript still available. For instance, any link set up using ``.jslink`` will still be connected, as will widget states collected using ``.embed()``.


**Q: How can I deploy a Panel app for others to use?**

**A:** There are many options available; see the Deployment section of the user manual. The basic idea is if you can log into a machine and launch a web server process, you can use ``panel serve`` there


**Q: Is Panel 'Shiny for Python'?**

**A:** Yes and no. Yes, in the sense that all the bold text on Shiny's home page (as of 11/2019) is also true of Panel, once you replace "Shiny" with "Panel" and "R" with "Python":

- "[Panel] is an [Python] package that makes it easy to build interactive web apps straight from [Python]"
- "[Panel] combines the computational power of [Python] with the interactivity of the modern web"
- "[Panel] apps are easy to write. No web development skills are required"
- "Put your [Panel] app on the web by using your own servers or [a] hosting service"

That said, Panel is in no way a clone of Shiny; Panel is a complete solution for browser-based interactivity, whether by adding a single widget to a notebook cell or by building a complex multipage app, designed to support the entire data-science workflow. Panel is also not associated with any particular public hosting provider, unlike Shiny.


**Q: Can Panel be used like Powerpoint?**

**A:** Panel works very well with `RISE <https://github.com/damianavila/RISE>`__, which lets a Jupyter notebook (including any Panel layouts) be used for a fully interactive full-screen presentation. Panel 1.0 also includes a native `SlidesTemplate <https://panel.holoviz.org/reference/templates/Slides.html>`__ similar to RISE.


**Q: What performance limitations does Panel have?**

**A:** Performance of a Panel app is generally limited by the underlying contents of the page, rather than by Panel itself. Panel apps can take a long time to launch initially if the script requires loading a large file, and Panel allows arbitrary computations to be performed on any interactive event (e.g. a mouse click or slider interaction), some of which may be slow to compute. Panel works well with the `Numba <http://numba.pydata.org/>`__ Python compiler and with the `Dask <https://dask.org/>`__ distributed computing library, which should allow you to get all the speed you need if you have sufficient processing power available.


**Q: Is support for geographic maps included with Panel?**

**A:** Panel supports displaying and working with almost anything, including geographic maps.  Panel is part of the `HoloViz <https://holoviz.org>`__ suite of tools, which includes the `GeoViews <https://geoviews.org>`__ package that works seamlessly with Panel to create fully interactive map-based apps with just a few lines of code. Most other Python map tools should also work!


**Q: How stable is Panel?**

**A:** Panel has been in continuous development and improvement since 2018, and is based on infrastructure from the Bokeh project that has been continuously improved since 2012.  Panel has very rapidly established a stable API and a large and active userbase, making the project already fully stable for production applications. New features are appearing rapidly, but generally without any changes to existing API.


**Q: How does Panel fit into the Python ecosystem?**

**A:** Panel can be used in an almost infinite variety of settings, so that's a very difficult question to answer. But we can tell you how we *designed* Panel, and how it fits with the other tools we develop or use frequently: `HoloViz ecosystem <http://holoviz.org/background.html#the-holoviz-ecosystem>`__.


**Q: Can Panel be used for real-time or streaming display updates?**

**A:** Yes! Panel apps are reactive to events in general, whether those events come from user interactivity or any other source. E.g. it works well with the `Streamz <https://streamz.readthedocs.io/en/latest/>`__ library for processing streaming data sources.

**Q: Can Panel make multipage applications?**

**A:** Of course! Panels can completely reconfigure themselves as needed, so it is possible to build just about anything you can see in a web page. In practice, one of these approaches can probably do what you want:

- Panel `Pipelines <user_guide/Pipelines.html>`__ provide an easy way to build a workflow where users first start on one page, make selections, then move to subsequent pages.  Pipelines can be linear (with one following page each time) or branching (with choices made on one page determining where to go on the next).
- Panel `Tabs <reference/layouts/Tabs.html>`__ let you provide users with a selection of different panels to choose from in any order, using one at a time.
- Bokeh/Panel `Templates <user_guide/Templates.html>`__ let you create arbitrary HTML/JS/CSS web pages around your panel components, where you can provide any control mechanism you like (though with a lot more effort than pipelines or tabs, unless you can copy an existing template).
- `Bokeh embed functions <http://docs.bokeh.org/en/1.3.2/docs/user_guide/embed.html>`__ allow you to embed static or server based Panel objects into your existing website.

**Q: Which server architecture should I use with Panel?**

**A:** Panel can be used with the basic Python interpreter to generate HTML files for emailing or putting on a web server, but if any action in the panel requires live execution of Python code, you will need to start a Python server process with a "comms" mechanism for communicating between Python and the JavaScript front-end that runs in the web browser.  Panel supports three server/comms technologies, each with their own intended uses:

+---------------------------------------+-----------------+--------------------------+-------------------+
|                                       | Jupyter         | Voila                    | Bokeh Server      |
+=======================================+=================+==========================+===================+
|Supports Panel apps                    | Yes             | Yes (via jupyter_bokeh)  | Yes               |
+---------------------------------------+-----------------+--------------------------+-------------------+
|Supports notebook layout (code cells)  | Yes             | Yes, optionally          | No                |
+---------------------------------------+-----------------+--------------------------+-------------------+
|Allows code editing                    | Yes             | No                       | No                |
+---------------------------------------+-----------------+--------------------------+-------------------+
|Supports web-page layout               | No              | Yes                      | Yes               |
+---------------------------------------+-----------------+--------------------------+-------------------+
|Supports ipywidgets                    | Yes             | Yes                      | No (as of 10/2019)|
+---------------------------------------+-----------------+--------------------------+-------------------+
|Can designate each output for display  | N/A             | No (except with template)| Yes               |
+---------------------------------------+-----------------+--------------------------+-------------------+
|Allows shared state across sessions    | No              | No                       | Yes               |
+---------------------------------------+-----------------+--------------------------+-------------------+

Panel works seamlessly with Jupyter notebooks for interactive editing, and it uses Bokeh Server to serve apps by default (aliasing it as ``panel serve``). Panel can also be used with Voila if you install the separate ``jupyter_bokeh`` library, which lets you incorporate ipywidgets-based tools into the same app as Panel objects. Other server technologies like Streamlit and Dash do not currently provide full support for Panel; they can typically display Panel objects but don't support the bidirectional communication needed for full Python-backed panel interactivity.


**Q: How does Panel relate to other widget/app/dashboard tools?**

**A:** Python has a rich, dynamic, and ever-expanding ecosystem, so any comparison can quickly go out of date. Also, most tools compare to only a small part of what Panel provides, as Panel is designed to support the entire life cycle of working with data: from initial exploration, to adding custom interactivity to make one-off analyses easier, to building a complex dashboard from multiple components, to deploying your polished Python-backed dashboard in a public-facing or on-premises private server, and then iterating by bringing those same components back to the notebook for further exploration and improvement. Other tools support *some* of the same capabilities, but by focusing on only one part of this life cycle they typically require you to start over when you need to use your work in a different way.

The `technology comparisons section <https://panel.holoviz.org/explanation/index.html#technology-comparisons>`__ describes some of these differences in detail, but at a high level:

+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|                                      | Panel           | ipywidgets           | Bokeh           | Streamlit          | Dash (Plotly)          | Shiny              |
+======================================+=================+======================+=================+====================+========================+====================+
|Provides widgets and layouts          | Yes             | Yes                  | Yes             | Yes                | Yes                    | Yes                |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports callbacks on plots           | Yes             | Yes                  | Yes             | No                 | Yes                    | Yes                |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports incremental plot updates     | Yes             | Yes                  | Yes             | Yes (in some cases)| Yes                    | Yes                |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Fully usable in Jupyter               | Yes             | Yes                  | Yes, with       | No                 | No, only via iframe    | No                 |
|                                      |                 |                      | jupyter_bokeh   |                    |                        |                    |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports static HTML export from      | Yes             | Not without a special| Yes             | No                 | No                     | No                 |
|notebooks (for reports, docs, etc.)   |                 | embedding procedure  |                 |                    |                        |                    |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports Matplotlib plots             | Yes             | Yes                  | No              | Yes                | With a separate adapter| No                 |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports Bokeh plots                  | Yes             | Yes                  | Yes             | Yes                | With a separate adapter| No                 |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports Plotly plots                 | Yes             | Yes                  | No              | Yes                | Yes                    | Yes                |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports R ggplot plots               | Yes             | No                   | No              | No                 | No                     | Yes                |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports Altair/Vega plots            | Yes             | Yes                  | No              | Yes                | With a separate adapter| Yes                |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Supports Django and Django channels   | Yes             | No                   | Yes             | No                 | No                     | No                 |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Allows separating business logic from | Yes             | No                   | No              | No                 | No                     | No                 |
|presentation                          |                 |                      |                 |                    |                        |                    |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+
|Servers supported                     | Jupyter, Bokeh, | Jupyter, Voila       | Jupyter, Bokeh, | Streamlit          | Dash                   | Shiny server       |
|                                      | Voila           |                      | Voila           |                    |                        |                    |
+--------------------------------------+-----------------+----------------------+-----------------+--------------------+------------------------+--------------------+

Each of these libraries are free, open-source software packages, but all of them can be used with the commercial
`Anaconda Enterprise (AE5) <https://www.anaconda.com/enterprise/>`__ server product, and some can be used with other commercial servers
(Shiny, with `Shiny Server <https://www.rstudio.com/products/shiny-server-pro>`__, Streamlit, with `Streamlit Teams`, and Dash, with
`Dash Enterprise <https://plot.ly/dash>`__), to provide on-premises authenticated deployment within a private network.  Most of the servers (including Jupyter, Bokeh Server, Voila, and Dash) can be also deployed on the public sites `mybinder.org <https://mybinder.org>`__ or `heroku <https://www.heroku.com>`__.
