You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/blog/posts/2025-07-23-parameterized-reports-python/index.qmd
+19-15Lines changed: 19 additions & 15 deletions
Original file line number
Diff line number
Diff line change
@@ -19,20 +19,20 @@ lightbox: true
19
19
20
20
## Based on a talk at SciPy 2025
21
21
22
-
This post is based on the talk "From One Notebook to Many Reports: Automating with Quarto" delivered at [SciPy 2025](https://www.scipy2025.scipy.org), July 2025 by Charlotte Wickham.
22
+
This post is based on the talk "From One Notebook to Many Reports: Automating with Quarto" delivered at [SciPy 2025](https://www.scipy2025.scipy.org) by Charlotte Wickham.
23
23
You can find the slides at [cwickham.github.io/one-notebook-many-reports](https://cwickham.github.io/one-notebook-many-reports/) and example code at [github.com/cwickham/one-notebook-many-reports](https://github.com/cwickham/one-notebook-many-reports).
24
24
25
25
:::
26
26
27
27
## The Problem: Repetitive Reporting
28
28
29
-
Would you rather read a generic "Climate summary" or a "Climate summary for _exactly where you live_"? Reports that are personalized to a specific situation increase understanding, engagement, and connection. But producing many customized reports manually is tedious and error-prone.
29
+
Would you rather read a generic "Climate summary" or a "Climate summary for _exactly where you live_"? Reports that are personalized to a specific situation increase engagement and connection. But producing many customized reports manually is tedious and error-prone.
30
30
31
-
Quarto solves this with parameterized reports—-you create a single document template, then render it multiple times with different parameter values to generate customized outputs automatically.
31
+
Quarto solves this with parameterized reports---you create a single document template, then render it multiple times with different parameter values to generate customized outputs automatically.
32
32
33
33
A great example is the customized soil health reports from Washington Soil Health Initiative's [State of the Soils Assessment](https://washingtonsoilhealthinitiative.com/state-of-the-soils/), presented at posit::conf(2023) by [Jadey Ryan](https://jadeyryan.com) (watch on [YouTube](https://youtu.be/lbE5uOqfT70?si=C-d5U5Q2VXo1wlDs)). Jadey demonstrated this approach using R and plain text Quarto files (`.qmd`).
34
34
35
-
This post shows you how to apply the same principles using Python: I'll walk through converting a Jupyter notebook (`.ipynb`) into a parameterized report, then automating the generation of multiple customized outputs. Then I'll show you how to make those reports look professionally polished.
35
+
This post shows you how to apply the same principles using Python: we'll walk through converting a Jupyter notebook (`.ipynb`) into a parameterized report, then automating the generation of multiple customized outputs. Then I'll give you some tips for making your reports look polished.
36
36
37
37
## The Solution: Parameterized Reports
38
38
@@ -48,7 +48,7 @@ You can see the full notebook, [`corvallis.ipynb`, on GitHub](https://github.com
48
48
49
49
- The document options specify `echo: false` so no code appears in the final output, and `format: typst` so the output is a PDF produced via [Typst](https://typst.app), a modern alternative to LaTeX.
50
50
51
-
This single notebook can be rendered:
51
+
This single notebook can be rendered with Quarto:
52
52
53
53
```{.bash filename="Terminal"}
54
54
quarto render corvallis.ipynb
@@ -62,7 +62,7 @@ Now, imagine we want to create this report for the 50 largest cities in Oregon.
62
62
Here's the steps we'll take:
63
63
64
64
1. Turn hardcoded values into variables
65
-
2.Make those variables parameters by tagging the cell
65
+
2.Declare those variables parameters
66
66
3. Render the notebook with different parameter values
67
67
4. Automate rendering with many parameter values
68
68
@@ -135,10 +135,10 @@ We can also use an f-string here to include the `city` variable:
135
135
Now, we should be able to test our changes by explicitly setting the `city` variable to something other than "Corvallis" and re-running the cells.
136
136
Since our report is no longer specific to Corvallis, we can rename it `climate.ipynb`.
137
137
138
-
### 2. Make variables into parameters
138
+
### 2. Declare those variables parameters
139
139
140
140
Now we have a variable that represents the parameter, we need to let Quarto know it's a parameter.
141
-
Quarto's parameterized reports are implemented using [Papermill](https://papermill.readthedocs.io/en/latest/), and inherits Papermill's approach: tag the cell containing the parameter with `parameters`.
141
+
Quarto's parameterized reports are implemented using [Papermill](https://papermill.readthedocs.io/en/latest/), and inherit Papermill's approach: tag the cell defining the parameter with `parameters`.
142
142
143
143
In Jupyter, you can add this tag through the cell toolbar:
144
144
@@ -172,19 +172,21 @@ params:
172
172
---
173
173
```
174
174
175
+
In `knitr`, parameters are accessed as elements of `params`, e.g. `params$city`, rather than as global variables like `city`.
176
+
175
177
:::
176
178
177
179
You can see the updated notebook (now a parameterized report), [`climate.ipynb`, on GitHub](https://github.com/cwickham/one-notebook-many-reports/blob/main/03-many-reports/climate.ipynb).
178
180
179
181
### 3. Render with different parameter values
180
182
181
-
If we render the notebook now, it will still produce the same report for Corvallis, because we haven't changed the parameter value:
183
+
If we render `climate.ipynb`, it will still produce the same report for Corvallis, because we haven't changed the parameter value:
182
184
183
185
```{.bash filename="Terminal"}
184
186
quarto render climate.ipynb
185
187
```
186
188
187
-
But we can now pass parameter values to Quarto when we render with the `-P` flag:
189
+
But we can now pass parameter values to Quarto with the `-P` flag:
188
190
189
191
```{.bash filename="Terminal"}
190
192
# Generate report for Portland
@@ -199,7 +201,7 @@ We've also added `--output-file` to ensure each report gets its own filename.
199
201
### 4. Automate rendering with many parameter values
200
202
201
203
To generate all 50 reports, we need to run `quarto render` 50 times, each time with a different city as the parameter value.
202
-
You could automate this in many ways, but let use a Python script.
204
+
You could automate this in many ways, but let's use a Python script.
203
205
For example, you might have a dataset of cities and their corresponding output filenames:
204
206
205
207
```python
@@ -209,7 +211,7 @@ cities = pl.DataFrame({
209
211
})
210
212
```
211
213
212
-
I've generated a small example above, but in reality you would likely read `cities` in from a CSV file.
214
+
I've generated a small example above, but in reality you would likely read `cities` in from a file.
213
215
Then you could iterate over the rows of this dataset, rendering the notebook for each city:
214
216
215
217
```python
@@ -231,7 +233,7 @@ However, if you are targeting `typst` you can take advantage of additional featu
231
233
232
234
### Brand.yml
233
235
234
-
Quarto supports [brand files](https://posit-dev.github.io/brand-yml/)that automatically apply your organization's colors, fonts, and logos across your reports:
236
+
Quarto supports [brand.yml](https://posit-dev.github.io/brand-yml/)a way to specify colors, fonts, and logos:
235
237
236
238
```{.yaml filename="_brand.yml"}
237
239
color:
@@ -250,8 +252,10 @@ logo:
250
252
medium: logo.png
251
253
```
252
254
253
-
Place this file in your project, and Quarto automatically applies your branding to all generated reports.
254
-
You can see a full example of using `_brand.yml` with `climate.ipynb` at [cwickham/one-notebook-many-reports/04-branded-reports](https://github.com/cwickham/scipy-talk/tree/main/04-branded-reports).
255
+
Quarto will detect the `_brand.yml` file and apply the colors, fonts and logo to your report.
256
+
Colors and fonts in your figures will need to be customized in your code, but that is made much easier with the [brand-yml](https://posit-dev.github.io/brand-yml/pkg/py/) Python package which imports your values from `_brand.yml`.
257
+
258
+
You can see a full example of using `_brand.yml` with `climate.ipynb` at [cwickham/one-notebook-many-reports/04-branded-reports](https://github.com/cwickham/scipy-talk/tree/main/04-branded-reports), and learn more about Quarto's support for brand in the [Brand guide](https://quarto.org/docs/authoring/brand.html).
0 commit comments