rstudio / reticulate

R Interface to Python
https://rstudio.github.io/reticulate
Apache License 2.0
1.68k stars 327 forks source link

better support for Plotly renderers #1540

Open cderv opened 8 months ago

cderv commented 8 months ago

This is the result of an investigation for

Context

Plotly in python offers some renderers configurations : https://plotly.com/python/renderers/#interactive-renderers

In Quarto we do some adjustment in Jupyter context - by default we set notebook_connected, unless in format: dashboard where we use notebook by default. We then handle the dependencies, and add possibly missing require.js and jQuery

It happens that there is some difference when using reticulate and plotly in Dashboard with Jupyter engine and plotly. So I looked into it to understand.

This raises some questions.

reticulate behavior.

I was curious of which renderers was used in reticulate context. Quarto does not do anything for R on this.

I saw that reticulate is setting a default if none set https://github.com/rstudio/reticulate/blob/b1c33d5797b1478ebddf876f0284ac953b086c0d/R/knitr-engine.R#L567-L576

Though from some test, I don't think this is applied. It seems browser is the default one.

---
title: "Test"
output: 
  html_document:
    self_contained: false
    keep_md: true
---

```{r}
library(reticulate)

Page 1

import plotly.graph_objects as go
import plotly.io as pio
pio.renderers
fig = go.Figure()

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

fig.show()
![image](https://github.com/rstudio/reticulate/assets/6791940/78f206dc-5917-4f19-b892-beeb1049faba)

Changing the value of this to something like `notebook_connected` for example, does not work. 

````markdown
```{python}
import plotly.graph_objects as go
import plotly.io as pio
pio.renderers.default = "notebook" # or "notebook_connected"
pio.renderers

Plots does not show. Because plotly.js is not included. This includes also setting to the supposed default `plotly_mimetype+notebook`

So I looked at how the plotly output and dependencies are handled in **reticulate**
This goes in there
https://github.com/rstudio/reticulate/blob/b1c33d5797b1478ebddf876f0284ac953b086c0d/R/knitr-engine.R#L710-L716

Looking at the intermediate .md file, I noticed that the plotly js deps was not included in the raw block created. And it is not included as HTML dependencies in includes. 

So somehow, it is not catched. 

Looking in debug mode, this is what I noticed in such mode `plotly_mimetype+notebook`. I believe the dependency is something printed as stdout and captured - which is currently un-used. 
I did the following at the breakpoint at code above 
````r
capt <- py_capture_output({
    data <- as_r_value(value$`_repr_html_`())
})

and then

I don't know if notebook is really supposed to work with reticulate and if it is required to make it works, but this raises question on plotly handling to me in knitting context.

We should be able to catch dependencies and includes it as knit_meta like others. I don't know if browser renderers is a good default also (or an expected default).

Happy to discuss and work on something. I believe there needs to be some adaptation for correct rendering in Quarto context.

t-kalinowski commented 7 months ago

If I recall correctly, I started setting a default renderer specifically for CI---on Ubuntu running in headless mode on GHA runners, the default render would be unset, result in an error. As far as I know, this was never a user issue, just our own CI that was failing.

I'm happy to make any changes you recommend! At this point you're more familiar with plotly internals, and any second order effects in quarto or rmarkdown that changes to this code might have. Suggestions welcome :)