quarto-dev / quarto-cli

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

Plotly image does not render correctly when rendering with GH actions #5766

Open juliasilge opened 1 year ago

juliasilge commented 1 year ago

Bug description

When using Plotly with Quarto on GH pages, the plot does not render.

Steps to reproduce

I made a small repo to demonstrate the problem:

Expected behavior

When I publish with GH pages, I expect the image to be rendered on this page: https://juliasilge.github.io/plotly-quarto-ghpages/

Actual behavior

There is a blank space where the image should be. I can write the HTML to a file and then include that, but that is not as expected.

Your environment

This happens when publishing on GH pages, like so: https://github.com/juliasilge/plotly-quarto-ghpages/blob/main/.github/workflows/quarto-publish.yaml

The page looks fine if I render locally.

Quarto check output

You can look at the GH action workflow to see which versions of Quarto and such are being used.

cscheid commented 1 year ago

(Just adding some information)

The error appears to be coming from the fact that require is missing in JavaScript, which makes me suspect some kind of problem capturing the emitted javascript dependencies. I also can't seem to trigger the problem locally, either with 1.3.353 (the version being used above), or main.

cscheid commented 1 year ago

There's definitely something funky happening on compile. It looks like the output went to the terminal stdout rather than being captured on the notebook: https://github.com/juliasilge/plotly-quarto-ghpages/actions/runs/5092338378/jobs/9153655952

cderv commented 1 year ago

@cscheid you tagged Jupyter, but I believe this is knitr related. This document has a R chunk so even with python chunk, engine: knitr will be used.

It looks like the output went to the terminal stdout rather than being captured on the notebook

Really interesting ! Thanks for catching this.

I think this could come from some recent changes in knitr regarding progress bar that seems related.

@juliasilge you could try updating to pin knitr 1.41 and see if this is still happening ? 1.42 is the version with the progress bar change.

juliasilge commented 1 year ago

The "real" example where we saw this problem also had both R and Python in the document: https://github.com/rstudio/vetiver.rstudio.com/blob/main/learn-more/metrics-metadata.qmd

cderv commented 1 year ago

@juliasilge would it be possible to pin knitr 1.41 and see if it fixes the CI building ?

juliasilge commented 1 year ago

It looks like it does not. I installed knitr 1.41 and added session info so you can see that: https://juliasilge.github.io/plotly-quarto-ghpages/

cderv commented 1 year ago

Thank you. Then it is possibly not knitr. This is really weird issue. I need to find where (and which tool) is doing the cat()-ing of the dependency string into the wrong place. Some configuration or tool. I'll try to debug that.

Possibly related to reticulate as this is a python chunk output.

Thank you for building the repo for testing

fradav commented 9 months ago

Hi,

We also encountered this on an 1.4 prerelease https://github.com/computorg/computo-quarto-extension Any news on the issue?

Regards

cscheid commented 9 months ago

@fradav We need a complete reproducible example from you in order to be able to help.

cscheid commented 9 months ago

(@cderv please feel free to change the milestone. I'm just making sure we have no issues that are not assigned anywhere)

fradav commented 9 months ago

@fradav We need a complete reproducible example from you in order to be able to help.

Sorry for the delay. Sure you could just fork the computorg/computo-quarto-extension repo, activate the gh-pages et let the actions deploy the site like there: https://computo.sfds.asso.fr/computo-quarto-extension/#python You can see there is a blank space instead of the plotly graph.

To be noted:

cderv commented 9 months ago

@fradav can you share link to log of a deployement ?

We noticed in other OP example that some output were not sent in the right place... I would like to check the knitting log output from the rendering.

fradav commented 9 months ago

Sure: https://github.com/computorg/computo-quarto-extension/actions/runs/6981929886/job/19000061336

fradav commented 9 months ago

The main github action log: https://github.com/computorg/computo-quarto-extension/actions/runs/6981744969/job/18999525208 and the knitting log doesn’t seem out of the ordinary:

processing file: computo-quarto-extension.qmd
1/11               
2/11 [r-code]      
3/11               
4/11 [fig-plotly]  
5/11               
6/11 [fig-gg]      
7/11               
8/11 [fig-ggplotly]
file:////tmp/Rtmpk3ptcX/file67c5313c798c/widget67c518[62](https://github.com/computorg/computo-quarto-extension/actions/runs/6981744969/job/18999525208#step:10:64)4aa7.html screenshot completed
9/11               
10/11 [cars]        
11/11               
output file: computo-quarto-extension.knit.md

pandoc 
  to: latex
  output-file: computo-quarto-extension.tex
  standalone: true
  pdf-engine: lualatex
  variables:
    graphics: true
    tables: true
  default-image-extension: pdf
  number-sections: true
  toc: true

metadata
  block-headings: true
  knitr:
    opts_chunk:
      screenshot.opts:
        cliprect: viewport
        vwidth: [64](https://github.com/computorg/computo-quarto-extension/actions/runs/6981744969/job/18999525208#step:10:66)0
        vheight: 400
  toc-title: Contents
  code-copy: true
  code-block-background: true
  papersize: a4
  geometry:
    - a4paper
    - textheight=24cm
    - textwidth=15.5cm
  fontfamily: libertinus
  fontsize: 11pt
  monofont: Latin Modern Mono
  monofontoptions:
    - Scale=0.92
  title: Computo Journal Format
  subtitle: To be used as template for contribution to Computo
  date: 01/02/2023
  date-modified: last-modified
  author:
    - name: The Computo Team
      corresponding: true
      email: computo@sfds.asso.fr
      url: 'https://computo.sfds.asso.fr'
      orcid: 0000-0000-0000-0000
      affiliations:
        - name: Société Française de Statistique
          department: Statistique
          address: IHP
          city: Paris
          country: France
          postal-code: [75](https://github.com/computorg/computo-quarto-extension/actions/runs/6981744969/job/18999525208#step:10:77)005
    - name: a friend
      affiliations:
        - Another Affiliation
  description: |
    This document provides a template based on the quarto system for contributions to Computo. The github repository in itself provides a specific quarto extension useful for authors (and editors!).
  keywords:
    - template
    - quarto
    - R
    - Python
    - reproductibility
  doi: 10.xxxx/xxx-xxx
  citation:
    type: article-journal
    container-title: Computo
    doi: 10.xxxx/xxx-xxx
    url: 'https://github.com/computorg/computo-quarto-extension'
    issn: 2824-[77](https://github.com/computorg/computo-quarto-extension/actions/runs/6981744969/job/18999525208#step:10:79)[95](https://github.com/computorg/computo-quarto-extension/actions/runs/6981744969/job/18999525208#step:10:97)
  bibliography:
    - references.bib
  google-scholar: true
  github-user: computorg
  repo: computo-quarto-extension
  draft: true
  published: false

processing file: computo-quarto-extension.qmd
1/11               
2/11 [r-code]      
3/11               
4/11 [fig-plotly]  
5/11               
6/11 [fig-gg]      
7/11               
8/11 [fig-ggplotly]
9/11               
10/11 [cars]        
11/11               
output file: computo-quarto-extension.knit.md
cderv commented 9 months ago

Thanks a lot. Nothing indeed.

Though now I noticed that both example happens with Python code chunk using plotly inside .qmd document run with knitr engine. This shows several layers of possible problem

I think looking into knitr + reticulate would be a way to see if this is related to how dependencies are generated and handled.

I'll try to find time to investigate that based on the two examples.

JavadocMD commented 6 months ago

We recently tangled with this issue as well, with an R/Python Quarto book-site. On both Windows and Ubuntu developer machines, we were able to successfully render the Plotly plots. But in the output from Github Actions and an Ubuntu server (AWS EC2), the plot would show as a blank space with errors in the browser console.

Our observation was that when rendered on the server, the plotly output would render as though using plotly.io.to_html(figure, include_plotlyjs="require") by default. And when running on our developer machines, would render as though using plotly.io.to_html(figure, include_plotlyjs="cdn") by default. And the server version breaks because require.js is never loaded by the rendered HTML. (I tried loading and configuring require.js myself, but this just made it work on the server and break for local dev.)

Some version info:

Workaround

My workaround was to add the plotly js myself (in _quarto.yml):

format:
  html:
    ...
    include-in-header:
      text: |
        <script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.27.1/plotly.min.js" integrity="sha512-R4Vz0/42Zw4rKUc8nc8TuKQGMtOMzCHxtXIFQoCB/fOT3q+L8f5l2s8n3CZsbJveMhoAV9yP8yWdj8vzwQx0hA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

And then in my .qmd, being explicit about rendering the plot without including plotly js:

import plotly.io as pio
from IPython.display import HTML
html = pio.to_html(figure, include_plotlyjs=False)
HTML(html)

This works for both environments.

Speculation

I can only speculate about the reason for the difference between default rendering modes, other than it does appear as though plotly does some "magical detection" to decide how to render, and I suppose that's failing when quarto is in the mix. Maybe has something to do with the fact that our developer machines aren't headless but the servers are? Or perhaps my Ubuntu workstation has some package installed that the Ubuntu server did not.

cscheid commented 6 months ago

@JavadocMD We have some logic to use plotly's notebook_connected mode, though I'm not aware of include_plotlyjs or other plotly options. Is there a chance you can try adding plotly-connected to the execution metadata in your files? That'd be something like:

engine:
  jupyter:
    plotly-connected: true

That should turn on this code path on our side:

  import plotly.io as pio
  if plotly_connected:
    pio.renderers.default = "notebook_connected"
  else:
    pio.renderers.default = "notebook"
JavadocMD commented 6 months ago

I'm fuzzy on the metadata -- as you typed it I get errors:

ERROR: Validation of YAML front matter failed.
ERROR: In file acs_commuting.qmd
(line 4, column 3 through line 5, column 26) Field "engine" has value

jupyter:
  plotly-connected: true

The value must instead be a string.
3: engine:
4:   jupyter:
    ~~~~~~~~~
5:     plotly-connected: true
  ~~~~~~~~~~~~~~~~~~~~~~~~~~
6: ---
✖ The value

jupyter:
  plotly-connected: true

is of type object.
ℹ The error happened in location engine.

ERROR: Render failed due to invalid YAML.

But I think I got the result you were looking for by putting just engine: jupyter in. That breaks R cells but does switch the default plotly renderer from plotly_mimetype+notebook (which is where it was originally) to notebook_connected; and then the resulting plot works. (I added a print(pio.renderers.default) to a code cell.)

The resulting markup uses SVG and require, but this time correctly loads require.js in the document <head>.

image

Not sure if that's helpful, but I'm happy to try things out.

cscheid commented 6 months ago

I apologize, I hadn't read your post closely enough to realize you said the page contained both R and Python code cells. In that case, the fix I suggested wouldn't have worked anyway. That's because mixed R+Python pages go through the knitr engine, which uses reticulate. I suspect someone has to teach reticulate to set up the equivalent of notebook_connected in Plotly.

cderv commented 1 month ago

Just cross referencing for future me as it could be related :

kcarnold commented 1 day ago

It's possible that work towards fixing this could also address this RStudio workspace bug.