quarto-dev / quarto-cli

Open-source scientific and technical publishing system built on Pandoc.
https://quarto.org
Other
3.91k stars 322 forks source link

Quarto Dashboard python plotly unexpected behavior #8910

Open javendaXgh opened 8 months ago

javendaXgh commented 8 months ago

Bug description

I am creating a dashboard with Quarto using RStudio. When using the "multiple pages" format and creating a plotly chart using python the following happens:

  1. In the plotly graph when clicking on any button of the "displayModeBar" all the elements of the dashboard page disappear and to make them reappear, in the "navigation bar" it is necessary to select any page to show the content again.
  2. If I try to disable the "displayModeBar" in the py-plotly chart, it does not do it.

This behavior does not occur if I generate the same chart using an R chunk with plotly in the same dashboard. It also does not occur if I generate a "Quarto Document" or if I stop using the "multiple pages".

Important, it only happens when placing the level 1 (#).

Sorry if I am omitting information or if there is a previous answer that addresses this issue. This is my first time submitting an issue and I tried to read the related issues beforehand.

Steps to reproduce

---
title: "Quarto Dashboard Test"
format: dashboard
---

```{r}
library(reticulate)

Page 1

#| title: pl in py
import plotly.graph_objects as go

fig = go.Figure()

fig=fig.add_trace(
    go.Scatter(
        x=[1, 2, 3],
        y=[1, 3, 1]))

fig.show(config={'displayModeBar': False})
#| title: pl in R
library(plotly)
df= data.frame( x=c(1, 2, 3),
                y=c(1, 3, 1))
plot_ly(data= df, x=~x)%>%
  add_trace( y= ~y, mode = 'lines+markers')

### Expected behavior

That when clicking on some element of the "displayModeBar" it behaves according to the applied functionality.

### Actual behavior

Part of the dashboard content disappears and it is necessary to select a page in the navigation bar to show all the content again.

<h4>Before click on displayModeBar</h4>

![Screenshot 2024-02-27 at 20 57 18](https://github.com/quarto-dev/quarto-cli/assets/20505279/e5870e0b-13b6-4aa3-9a61-55e8c98f3cf3)

<h4>After click on displayModeBar</h4>

![Screenshot 2024-02-27 at 20 57 29](https://github.com/quarto-dev/quarto-cli/assets/20505279/fee9eada-c869-4d81-a53a-4de310bc5aba)

### Your environment

- IDE: RStudio Version 2023.12.1+402 (2023.12.1+402)
- OS: MacOS Sonama 14.3.1

### Quarto check output

Quarto 1.4.550 [✓] Checking versions of quarto binary dependencies... Pandoc version 3.1.11: OK Dart Sass version 1.69.5: OK Deno version 1.37.2: OK [✓] Checking versions of quarto dependencies......OK [✓] Checking Quarto installation......OK Version: 1.4.550 Path: /Applications/quarto/bin

[✓] Checking tools....................OK TinyTeX: (external install) Chromium: (not installed)

[✓] Checking LaTeX....................OK Using: TinyTex Path: /Users/josemiguelavendanoinfante/Library/TinyTeX/bin/universal-darwin Version: 2023

[✓] Checking basic markdown render....OK

[✓] Checking Python 3 installation....OK Version: 3.12.2 Path: /opt/homebrew/opt/python@3.12/bin/python3.12 Jupyter: (None)

  Jupyter is not available in this Python installation.
  Install with python3 -m pip install jupyter

[✓] Checking R installation...........OK Version: 4.3.2 Path: /Library/Frameworks/R.framework/Resources LibPaths:

[✓] Checking Knitr engine render......OK

cscheid commented 8 months ago

Can you try to create a reproduction that doesn't require this? (That's not reproducible for us)

```{r}
library(reticulate)

Sys.unsetenv('RETICULATE_PYTHON')
use_python('/Users/...../bin/python3.10')
javendaXgh commented 8 months ago

I have modified it

cderv commented 8 months ago

I can reproduce with Plotly python 5.19 and latest quarto

rstudio_qFONpWfdiN

Note that the config does not seem to work with reticulate for me.

fig.show(config={'displayModeBar': False})

This still show the bar image

Anyhow, I don't see any error / message in browser console. So it seems like a bad interaction somehow...

We have another at:

This behavior does not occur if I generate the same chart using an R chunk with plotly in the same dashboard.

I don't know what the difference in integration is between Python package and R package for plotly. Could be a version difference...

It also does not happen when using Jupyter directly

---
title: "Quarto Dashboard Test"
format: dashboard
---

# Page 1

```{python}
#| title: pl in py
import plotly.graph_objects as go

fig = go.Figure()

fig=fig.add_trace(
    go.Scatter(
        x=[1, 2, 3],
        y=[1, 3, 1]))

fig.show()


So it seems to be a problem with py-plotly when used in **reticulate**.  We now we have differences, especially with plotly through **reticulate** not adapting the default renderers (https://plotly.com/python/renderers/#setting-the-default-renderer) 

We'll look into this to make the experience similar for R and Jupyter users. 

Quarto changes some settings for Jupyter engine for example, but when Python is used through Knitr engine. 
https://github.com/quarto-dev/quarto-cli/blob/2485d18a05cb8c12989e795ed01bb2cf7f43a0e3/src/resources/jupyter/lang/python/setup.py#L29-L39

It could be related (but I can make it works while testing right now)
cderv commented 8 months ago

I believe this is directly related to the renderers used for Plotly.

Changing it to iframe_connected for example solves the issue.

---
title: "Quarto Dashboard Test"
format: dashboard
keep-md: true
---

```{r}
library(reticulate)

Page 1

#| include: false
import plotly.graph_objects as go
import plotly.io as pio
pio.renderers.default = "iframe_connected"
#| title: pl in py
fig = go.Figure()

fig=fig.add_trace(
    go.Scatter(
        x=[1, 2, 3],
        y=[1, 3, 1]))

fig.show(config={'displayModeBar': False})

To be clear this is a test. `iframe_connected` could have other issues maybe with Dashboard. But this seems like a valid workaround in **knitr** context for Dashboard. 

As I am curious, I looked deeper. If I add this chunk to the dashboard for reticulate
````markdown
```{python}
import plotly.graph_objects as go
import plotly.io as pio
pio.renderers

It will show us in the dashboard produced that defaults with reticulate seems to be `browser` renderer. 

![image](https://github.com/quarto-dev/quarto-cli/assets/6791940/4604ba5f-01cd-412a-9d28-a6d444de6547)

Not sure how **reticulate** handles this one to extract the dependencies. But at this ends this is what seems to create the conflict with the Dashboard.

So I do think, this is related to **reticulate** handling of different Plotly renderers, and what can be supported with the Quarto Dahsboard format. 

In Quarto we do some processing regarding Plotly, and for `format: dashboard` we set `notebook` as the renderer, and for any other document this is `notebook_connected`

As mentioned, we set `notebook` or `notebook_connected` in there (this is what is required for usage with Jupyter. )
https://github.com/quarto-dev/quarto-cli/blob/2485d18a05cb8c12989e795ed01bb2cf7f43a0e3/src/resources/jupyter/lang/python/setup.py#L29-L39

If I do either of those for *reticulate** used plotly, then there will be missing JS deps (require.js and JQuery.js)

Quarto is adding the the missing deps when used in Jupyter engine
https://github.com/quarto-dev/quarto-cli/blob/2485d18a05cb8c12989e795ed01bb2cf7f43a0e3/src/core/jupyter/widgets.ts#L100-L112

But even adding those won't work because with **reticulate** because Plotly.js deps will be missing - It seems it does not handle those renderers. 

So we could try set some default for Plotly.js in R context, but **reticulate** would need to be first fixed. 
javendaXgh commented 8 months ago

@cderv thank you very much for your response and proposed solution

cderv commented 8 months ago

I opened discussion in reticulate to see how to improve this