Open spluque opened 2 years ago
I recommend using the :file /path/to/figure
header argument to save figures as png - it's simpler and requires less code. Check out the "Rich kernel output" section of the readme of this repo.
Ie:
#+BEGIN_SRC jupyter-python :session py :file junk.png :exports output
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(np.random.randn(10))
#+END_SRC
#+RESULTS:
: your figure will show up here as the link you specified in the header
I was hoping to be able to define the file path within the source block. For example, one block has pandas read a file from one path to generate a dataframe, produce a plot, and save a png in the same containing folder, with a name consistent with the base name of the input data file. The plot also needs to be closed.
It seems as if the example I showed should work, but something is botched with the generated link to the file. Using the built-in ob-python, with :session py :results file
header arguments, it returns the proper link as: [[file:junk.png]]
under #+RESULTS.
The :file /path/to/figure
feature is super nice, but it isn't always usable in more complicated scenarios. For instance, it doesn't work with the Altair plotting library, which only generates a PNG version of the figure in the process of saving it to disk.
A possible solution, lifted from here, is to set the mimetype of the output to text/org
, and generate the appropriate link yourself:
#+begin_src jupyter-python
import altair as alt
import seaborn as sns
from IPython.display import publish_display_data
iris = sns.load_dataset("iris")
chart = alt.Chart(iris).mark_circle().encode(
x="sepal_length",
y="sepal_width",
color="species",
)
fname = "chart.png"
chart.save(fname)
publish_display_data({"text/org": f"[[file:{fname}]]"})
#+end_src
#+RESULTS:
:RESULTS:
[[file:chart.png]]
:END:
See also https://github.com/nnicandro/emacs-jupyter/issues/237.
the Altair plotting library, which only generates a PNG version of the figure in the process of saving it to disk
Oops, just discovered this is not actually true. You can use a PNG renderer to make Altair output an image directly, which then works perfectly fine with :file ...
:
#+begin_src jupyter-python :file chart_via_renderer.png
alt.renderers.enable("png")
chart
#+end_src
#+RESULTS:
[[file:chart_via_renderer.png]]
Still, the mimetype workaround still works for more complicated workflows, where you want to generate the filename dynamically in code.
I've recently switched to
emacs-jupyter
for handling Python code blocks inorg-mode
. I want to save a plot topng
format, display it as#+RESULTS
, as well as export it. However, the block is returning a badly formatted link:Any pointers welcome.