Vector graphics export using nbconvert to LaTeX


#1

Dear all,

I am using Plot.ly offline in Jupyter Notebooks in Python. See the example code below. When exporting the notebook to LaTeX using nbconvert, the interactive PlotLy figure gets converted to PNG. Is there a way to make it export to vector graphics instead? (SVG, EPS or PDF). Is the PNG conversion done by nbconvert itself or by plotly or orca?

I know that I could either:

  • use the write_image method to save the figure to SVG, EPS or PDF. This is what I would use for publications, but for regular documents, I would like to avoid having to save figures manually before generating the LaTeX files
  • use to_image(fig, format=‘svg’) and then display the SVG using the IPython.display.SVG method. However, nbconvert fails at the moment because of SVG, the pull request is still pending: https://github.com/jupyter/nbconvert/pull/910

The code I use:

import plotly.offline as py
py.init_notebook_mode(connected=True)
import plotly.graph_objs as go

trace = go.Scatter(
    x = df.loc['A']['X'],
    y = df.loc['A']['Y'],
    mode='markers'
)
data = [trace]
layout = go.Layout(
    title = 'A',
    xaxis = dict(
        title = 'X'
    ),
    yaxis = dict(
        title = 'Y'
    )
)
fig = dict(data=data, layout=layout)
py.iplot(fig)

I use the following command in the terminal to convert the notebook to LaTeX:

jupyter nbconvert --template=myTemplate.tplx --to=latex myNotebook.ipynb

My setup:

  • Ubuntu 18.04 x64
  • conda environment containing:
    • plotly 3.7.0 from plotly conda channel
    • plotly-orca 1.2.1 from plotly conda channel
    • notebook 5.7.6 from conda-forge channel
    • jupyterlab 0.35.4 from conda-forge channel
    • nbconvert 5.4.1 from conda-forge channel

Thank you,
Best regards
GorgiAstro


#2

Hi @GorgiAstro,

Before running nbconvert, are you creating your notebooks in JupyterLab? If so, the png image that nbconvert is finding is actually generated by the @jupyterlab/plotly-extension extension. This extension automatically saves a png version of the figure back to the notebook on render. See:

Your usecase isn’t directly supported yet, but it’s one of the motivations for the plotly.io.renderers proposal (See https://github.com/plotly/plotly.py/issues/1459) that I wroteup a few days ago. Under this proposal you would put a line at the top of the notebook like.

import plotly.io as pio
pio.renderers.default = 'jupyterlab+svg`

Then every time a figure is displayed it would be stored to the notebook using both the plotly mimetype (the interactive type handled by @jupyterlab/plotly-extension) and svg. In JupyterLab you would get the interactive display, but nbconvert should pick up the svg format instead.

Feel free to chime in on https://github.com/plotly/plotly.py/issues/1459 with your use-case, and let me know if you’re interested in helping out with testing this workflow once we have some development builds ready.

-Jon


#3

Hi @jmmease,

Thank you for your answer. I am working in JupyterLab indeed.

I like your proposal for the plotly.io.renderers, the approach is elegant. I am definitely interested in helping out with testing, I subscribed to the Github ticket.

Cheers
GorgiAstro


#4

I have a PR ready to play with now. See https://github.com/plotly/plotly.py/pull/1474 and let me know if you give it a try!

-Jon


#5

Great, thanks a lot! I will give it a try tonight or tomorrow.

-GorgiAstro