I find it useful to convert from qmd to ipynb using quarto convert
where I can run code lines one cell at a time. Quarto can preview/render ipynb without re-running the cells, only displaying their outputs if they have been run. This is useful for interactive development and execution of a “Quarto document”. Once I am happy with the ipynb’s code output, I can convert back to qmd, going back and forth as needed.
I’m aware of what Quarto is, but also there’s no reason it can’t be made more interactive, and indeed the backends for other languages are more suited to interactivity.
I was just curious if there was interest in implementing these features in the julia one or not, but I guess I’ll take that as a “no”.
and indeed the backends for other languages are more suited to interactivity
Could you elaborate on that? As far as I know the R quarto experience in RStudio is not that different from the Julia experience in VSCode, just that you can optionally show output of code chunks inline in the qmd. But if I understand correctly, you don’t get “final” looking output inline (i.e. with all the correct formatting, because that needs pandoc). So the other option is preview mode of the whole document, which we also have.
So as far as I can see, you either go the jupyter notebook route and match python’s interactive experience, or you go the qmd route and are pretty close to R, minus the inline outputs which I guess could be added to the VSCode quarto extension.
I know the jupyter backend has an option for caching of outputs which I’d say is an okay start, and basically just a dumber version of reactivity.
We just released QuartoNotebookRunner 0.10. (This is not yet automatically used in the latest quarto prerelease, but you can test it out using the instructions at the end of this post This is now available starting with in prerelease Release v1.5.31 · quarto-dev/quarto-cli · GitHub)
This version adds the ability to use {r}
code blocks which are rendered using RCall.jl if it’s available. This is similar to using the R""
string macro but more convenient, plus you get correct R syntax highlighting:
You can also use parameterized notebooks now. You specify defaults in the frontmatter like this:
params:
a: 1
b: "2"
And then use these in your script as normal variables like
```{julia}
println("a is ", a, " and b is ", b)
```
You can then render the notebook with different parameters like quarto render somenotebook.qmd -P a:4
as otherwise described here Quarto – Parameters
How to test the latest QuartoNotebookRunner with quarto prereleases
Each quarto version specifies a specific QuartoNotebookRunner version it wants to use. That’s the one that automatically gets set up for you in the background. If you want to use a different version, for example to test this new functionality in 0.10, you can, from prerelease 1.5.30 on Release v1.5.30 · quarto-dev/quarto-cli · GitHub use the env variable QUARTO_JULIA_PROJECT
to set a different environment where quarto will try to load QuartoNotebookRunner from.
So you could do ]activate some/dir
then ]add QuartoNotebookRunner
and then QUARTO_JULIA_PROJECT=some/dir quarto render somefile.qmd
Really, really cool.
Is there some example of the use of {r}
blocks to create plots that we could look at? Perhaps in the test/examples directory of the QuartoNotebookRunner
package? I have been grepping around without success.
I found the test/examples/integrations subdirectory.
The latest prerelease has version 0.10 included Release v1.5.31 · quarto-dev/quarto-cli · GitHub
I have been using Weave.jl for writing documents that requires Julia code for a while. (Mostly for writing quizzes and exams for my teaching.) It has been adequate. But I noticed that Weave.jl seems to have been dormant for quite some time now. If you have tried both quarto and Weave, have you found something in Weave but is not supported by quarto?
I broke it too🤝!!
did you find any solution?
evaluate_raw_cells! / pwd() throws IOError: pwd(): no such file or directory · Issue #93 · PumasAI/QuartoNotebookRunner.jl · GitHub was fixed by try-catch pwd in case it's deleted after starting the server by jkrumbiegel · Pull Request #96 · PumasAI/QuartoNotebookRunner.jl · GitHub
Edit: … so quarto 1.5.31+ should not have the issue…
Is it possible to use quarto on a remote server? So that it renders locally, but runs code remotely.
Possibly, never tried something like that before. Perhaps asking on the main quarto forums would get you a more definite answer since this isn’t really specific to our Julia backend.
We have just released 0.12.0 of QuartoNotebookRunner.
The major new feature available in this version is the ability to run different Julia versions in individual notebooks. Previously a limitation in the serialization of data between notebooks and the main process required the Julia versions to match. This has now been lifted.
You can access this feature by adding a valid juliaup
channel to a notebook’s frontmatter, for example:
---
engine: julia
julia:
exeflags: ["+1.11.3"]
---
to run a notebook with Julia 1.11.3, the same syntax as starting a Julia REPL with a specific version. Note that QuartoNotebookRunner does not perform any behind-the-scenes management of juliaup
channels. You will need to ensure that they are already installed, as well as ensuring that you already have juliaup
installed.
It’s a rather large internal change to allow for this feature so if you run into any trouble then please open up issues and we’ll take a look.
Finally, there will be the usual delay in this version becoming available by default in quarto
itself. Until then you’ll need to set the QUARTO_JULIA_PROJECT
environment variable to a path to a Julia project directory that has version 0.12 of QNR already installed.
Version 0.13.0 of QuartoNotebookRunner.jl has been release.
The main new feature shipping with this version is the addition of support for running Python cells within our backend. This relies on PythonCall.jl for code evaluation, and so should support anything that that package supports, including importing external Python packages, such as plotting, pandas, etc. All you’ll need to do is add PythonCall
to you notebook’s Project.toml
and import
it into a cell at the start of the notebook, something like:
---
engine: julia
---
```{julia}
import PythonCall
```
```{python}
import seaborn as sns
tips = sns.load_dataset("tips")
sns.relplot(
data=tips,
x="total_bill", y="tip", col="time",
hue="smoker", style="smoker", size="size",
)
```
Ensure you’ve installed the seaborn
package before running it. Just use the conda
command that PythonCall adds to the Pkg mode.
Julia values can be directly interpolated using $
into Python code blocks, in the same way that we already support interpolation into R code blocks (managed by RCall.jl). This means that (if you really want to) you can use them all together and send R values to Python via Julia.
This is a very new feature addition, so might be buggy in places. Please do open issues if you run into any problems.
Currently quarto
won’t have the updated version of QNR installed by default, that’ll take a little time to become available there. In the interim you can use the QUARTO_JULIA_PROJECT
environment variable to set the path to a Julia environment that has an up-to-date version of the package.
Adding a little CSS snippet here for one possible way to disambiguate cells with different languages:
code.sourceCode.r::before{
content:url('https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/r/r-original.svg');
float:right;
width: 20px;
}
code.sourceCode.python::before{
content:url('https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/python/python-original.svg');
float:right;
width: 20px;
}
code.sourceCode.julia::before{
content:url('https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/julia/julia-original.svg');
float:right;
width: 20px;
}
That does look good - but it might be less obtrusive in grayscale?
It should suffice to add a filter: grayscale(1);
tag.
I was thinking something similar, but it would perhaps be better again (more visually consistent) to source icons from https://simpleicons.org and display them with say opacity: 0.4
.
code.sourceCode.r::before{
content:url('data:image/svg+xml; utf8, <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2.746c-6.627 0-12 3.599-12 8.037 0 3.897 4.144 7.144 9.64 7.88V16.26c-2.924-.915-4.925-2.755-4.925-4.877 0-3.035 4.084-5.494 9.12-5.494 5.038 0 8.757 1.683 8.757 5.494 0 1.976-.999 3.379-2.662 4.272.09.066.174.128.258.216.169.149.25.363.372.544 2.128-1.45 3.44-3.437 3.44-5.631 0-4.44-5.373-8.038-12-8.038zm-2.111 4.99v13.516l4.093-.002-.002-5.291h1.1c.225 0 .321.066.549.25.272.22.715.982.715.982l2.164 4.063 4.627-.002-2.864-4.826s-.086-.193-.265-.383a2.22 2.22 0 00-.582-.416c-.422-.214-1.149-.434-1.149-.434s3.578-.264 3.578-3.826c0-3.562-3.744-3.63-3.744-3.63zm4.127 2.93l2.478.002s1.149-.062 1.149 1.127c0 1.165-1.149 1.17-1.149 1.17h-2.478zm1.754 6.119c-.494.049-1.012.079-1.54.088v1.807a16.622 16.622 0 002.37-.473l-.471-.891s-.108-.183-.248-.394c-.039-.054-.08-.098-.111-.137z"/></svg>');
float:right;
width: 20px;
filter: opacity(0.25);
}
code.sourceCode.python::before{
content:url('data:image/svg+xml; utf8, <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z"/></svg>');
float:right;
width: 20px;
filter: opacity(0.25);
}
code.sourceCode.julia::before{
content:url('data:image/svg+xml; utf8, <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M11.138 17.569a5.569 5.569 0 1 1-11.138 0 5.569 5.569 0 1 1 11.138 0zm6.431-11.138a5.569 5.569 0 1 1-11.138 0 5.569 5.569 0 1 1 11.138 0zM24 17.569a5.569 5.569 0 1 1-11.138 0 5.569 5.569 0 1 1 11.138 0z"/></svg>');
float:right;
width: 20px;
filter: opacity(0.25);
}