-
Notifications
You must be signed in to change notification settings - Fork 6
/
index.qmd
952 lines (665 loc) Β· 25.8 KB
/
index.qmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
---
format:
revealjs:
theme: [default, style.scss]
highlight-style: github
width: 1400
css:
- https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css
---
## {.center}
::: {.notes}
Hi, I'm James
I'm D&DSL at 360info @ Monash Uni
Really excited to talk about Quarto
Some people today have used R Markdown and are wondering what this new thing is
Others might be notebook fans or have never used any tools in this space
That's okay - I'm going to cover all the basics and then talk a bit about why I think Quarto has a lot of potential
:::
<h1 class="text-indigo-pink">Quarto<h1>
<h2>Create beautiful documents with R, Python, Julia and Observable</h2>
::: {style="margin-top:50px"}
### JAMES GOLDIE {.text-orange-gold}
Data and Digital Storytelling Lead, 360info
:::
## Today {.center}
::: {.notes}
I want to get a feel for everyone's experience today, so I'm going to start out qith a quick poll
before i get into Quarto.
For people who've used these kinds of things before, Quarto has two really cool differences.
One is that it's language-independent, so anyone can use it
The other is that it adds a language called Observable JavaScript that makes learning JavaScript easier.
These two things give Quarto a really strong basis for helping data scientists learn to build compelling visualisations for the web.
:::
1. Hello!
2. What are reproducible reports?
3. What's Quarto? Why can anyone use it?
4. Web content
::: {style="margin-top:50px"}
### Slides
[**https://runapp2022.talks.jamesgoldie.dev**](https://runapp2022.talks.jamesgoldie.dev)
[(Code for these slides is at [**https://github.com/jimjam-slam/talk-runapp-quarto-2022**](https://github.com/jimjam-slam/talk-runapp-quarto-2022))]{style="font-size:1.2rem"}
:::
# Hi! {.text-wash-black background="linear-gradient(45deg, #00aadd, #66dd00)"}
## {.text-lime-cyan}
::: {.notes}
(click)
I've been working for 360info for about 9 months
We're a research-driven newswire, and we give everything away for free under Creative Commons so that all journalists can benefit from it
We're founded by Andrew Jaspan, the man who also founded The Conversation
As our team grows, I'm doing some of everything:
* analysing data
* build charts and maps
* working with our infrastructure partners
:::
::::: {.columns style="text-align:center;margin-top:50px;"}
:::: {.column width="50%" style="margin-top:50px"}
::: {.r-stack}
![](images/graduation.gif){.fragment .fade-in-then-semi-out fragment-index=1 style="width:70%;transform:rotate(-5deg);" fig-alt="A picture of me and my PhD supervisor, Lisa Alexander, at my graduation."}
![](images/mcccrh-zoom.png){.fragment .fade-in-then-semi-out fragment-index=2 style="transform:rotate(5deg);" fig-alt="A picture of me and MCCCRH staff members on Zoom."}
![](images/mcccrh.gif){.fragment .fade-in-then-semi-out fragment-index=3 style="transform:rotate(-1deg);" fig-alt="A picture of me and MCCCRH staff members on a work trip."}
![](images/mcccrh-projections.jpg){.fragment .fade-in-then-semi-out fragment-index=4 style="transform:rotate(1.5deg);" fig-alt="A picture of Graham Creed from the ABC presenting climate projections."}
![](images/mcccrh-7news.gif){.fragment .fade-in fragment-index=5 style="transform:rotate(-3.5deg);" fig-alt="A picture of Jane Bunn presenting statistics on shrinking winters."}
:::
::::
:::: {.column width="50%" style="margin-top:25px"}
::: {.fragment fragment-index=1}
I used to be a climate + health researcher
:::
::: {.fragment fragment-index=2}
β’
Worked with **[CLEX](https://climateextremes.org.au)** and **[MCCCRH](https://monash.edu/mcccrh)** on climate change communication
:::
::: {.fragment fragment-index=6}
β’
<!-- Now a data journalist with **[360info.org](https://360info.org)!** -->
Now I'm a data journalist with
[![](images/360logo.svg){style="width:50%;"}](https://360info.org)
:::
::::
:::::
## Poll: what tools do you use? {.text-lime-cyan}
::: {.notes}
Would love to find out more about all of you and what you're learning
No personal info in this poll, just 2 Qs
1. What have you used before?
2. What do you want to learn?
Take a moment to fill it in on your phone
Normally if you wanted to do a poll in a presentation, you'd use a third-party website like Slido and embed it
For today's poll I decided to take a risk and build it entirely in Quarto.
:::
:::: {.columns}
:::{.column width="40%"}
![](./images/qrcode-survey.png){fig-alt="A QR code for the survey."}
:::
::: {.column width="60%" .center}
<br>Take the survey at **<https://forms.gle/EdADv8GvDxUrrRmy8>**
:::
::::
## {.text-lime-cyan style="text-align: center;"}
```{ojs}
md`## Poll results (Respondents: ${respondentCount})`
```
```{ojs}
import { liveGoogleSheet } from "@jimjamslam/live-google-sheet";
import { aq, op } from "@uwdata/arquero";
surveyResults = liveGoogleSheet(
"https://docs.google.com/spreadsheets/d/e/" +
"2PACX-1vSVQzZlkSWWR38FRKyFbO2WGYo04ehrJt4TvWkRVOJ7WPRmfQzPAf7AjtyV2EjIY-2DwKW-SfzLoEQw/" +
"pub?gid=1368316628&single=true&output=csv",
15000, 1, 2);
respondentCount = surveyResults.length;
```
```{ojs}
// get the counts of people using and interested in tools
countsUsed = aq.from(surveyResults)
.derive({ used: d => op.split(d.responseUsed, ", ") })
.select("used")
.unroll("used")
.groupby("used")
.count()
.derive({ measure: d => "Have used" })
.rename({ used: "tool" })
```
```{ojs}
countsWant = aq.from(surveyResults)
.derive({ want: d => op.split(d.responseWant, ", ") })
.select("want")
.unroll("want")
.groupby("want")
.count()
.derive({ measure: d => "Want to learn" })
.rename({ want: "tool" })
```
```{ojs}
// combine the two counts into one dataset again
countsAll = [...countsUsed.objects(), ...countsWant.objects()];
plotUsed = Plot.plot({
marks: [
Plot.barX(countsAll, { y: "tool", x: "count", fill: "tool" }),
Plot.ruleX([respondentCount], { stroke: "#ffffff99" })
],
x : { label: "" },
y : { label: "", tickSize: 0 },
facet: { data: countsAll, x: "measure", label: "" },
marginLeft: 140,
style: {
width: 1350,
height: 500,
fontSize: 12,
}
});
```
<!-- keep a qr code up in the top-right corner -->
![](./images/qrcode-survey.png){style="position:fixed;top:0;right:0;width:140px;height:140px" fig-alt="A picture of a QR code to the survey."}
# What are <br>[reproducible reports?]{.hl .hl-gold} {.text-wash-black background="linear-gradient(45deg, #f37335, #fdc830)"}
## {background-image="images/confused-dog.jpg"}
::: {.notes}
If you work in Python or Julia, you may have heard of **notebooks**
R users might have heard of **reproducible reports**
All examples of **literate programming**
Literate programming is about _explaining your code_ by combining code with written prose and graphics
:::
##
::: {.notes}
Very nice to read!
Readable even if you didn't write it
File format is opaque and hard to version control
Files shared or hosted on special notebook services
:::
:::: {.columns}
::: {.column width="50%" style="margin-top:30px;"}
<h2 class="text-orange-gold">Notebooks</h2>
* Contain:
- Writing
- Code
- <span style="color:gold;">**Results in the file too**</span>
:::
::: {.column width="50%"}
![](images/notebook.png){fig-alt="A picture of a Jupyter notebook loaded into Visual Studio Code."}
:::
::::
## Reproducible reports {.text-orange-gold style="text-align:center"}
Source **documents** are **rendered** to produce **results**
::: {.notes}
R Markdown is more common among R users
Instead of code and results together, we _render_ a source document
Contains writing and code, but not results!
An R Markdown document is _rendered_. The final report is a separate file!
Plain text source file
Easy to see changes over time in version control
Docs, books, websites, presentations...
Need R to run it
:::
:::: {.columns}
::: {.column width="50%"}
![](images/rmd-source.png){fig-alt="An R Markdown source document in a plain text code editor"}
:::
<!-- ::: {.column width="20%"}
::: -->
::: {.column width="50%"}
![](images/rmd-render.png){fig-alt="An R Markdown document rendered into HTML with a plot in it."}
:::
::::
## The RMarkdown ecosystem {.text-orange-gold}
::: {.notes}
Because R Markdown gets rendered, it can make lots of different kinds of documents!
:::
::: {style="text-align:center;margin-top:175px;"}
R packages for just about every kind of document:
[`xaringan`](https://github.com/yihui/xaringan) β’ [`distill`](https://rstudio.github.io/distill) β’ [`blogdown`](https://bookdown.org/yihui/blogdown) β’ [`hugodown`](https://github.com/r-lib/hugodown) β’ [`bookdown`](https://bookdown.org) β’ [`thesisdown`](https://github.com/ismayc/thesisdown) β’ [`oxforddown`](https://ulyngs.github.io/oxforddown) β’ [`unswthesisdown`](https://github.com/jimjam-slam/unswthesisdown) β’ [`pagedown`](https://github.com/rstudio/pagedown) β’ [`flexdashboard`](https://pkgs.rstudio.com/flexdashboard/) β’ [`rmdformats`](https://github.com/juba/rmdformats) β’ [`rticles`](https://github.com/rstudio/rticles) β’ [`prettydoc`](https://prettydoc.statr.me/) β’ [`markdowntemplates`](https://github.com/hrbrmstr/markdowntemplates) β’ and more...
:::
# [Quarto:<br>[Literate programming for[everyone]{.hl .hl-purple}]{style="font-size:75%;"}]{style="color:white"} { background="linear-gradient(45deg, #4a00e0, #ff0099)"}
::: {.notes}
So we have two very different approaches to explaining your data.
Notebooks are a really nice writing experience, and it's good to have code and results in one place.
But they're difficult to share or collaborate on without dedicated services.
RMarkdown docs have a massive ecosystem for lots of different outputs, and they're very clear and easy to share. But not everyone uses R!
Quarto tries to have its cake and eat it too.
:::
## Notebooks or documents {.text-indigo-pink style="text-align:center"}
::: {.notes}
You don't have to choose between writing in notebooks or documents - they both work!
Here we have a Quarto report, written two different ways: a notebook and a document.
Either of these can be rendered - into a webpage, a blog post, a slideshow, a Word document, a PDF...
If you're used to documents, Quarto ones look almost the same!
We still have _chunk options_ (cell options for notebook people). They sit as special comments at the start of the cell, and they're written in YAML. You can add them to notebook cells too!
(The old RMarkdown way still works.)
Frontmatter still works largely the same as RMarkdown, but you can add it to notebooks too!
:::
![](images/notebook-vs-document.png){fig-alt="A picture of the same Quarto document side-by-side, written in notebook form on the left and document form on the right." style="width:100%; height:auto;"}
## R, Python, Julia {.text-indigo-pink style="text-align:center"}
::: {.notes}
The other big change here is that you can use your **favourite language** in **either format.**
You can write Python chunks in a document like the one on the right, and you can render it **without needing to have R installed.**
On the flip side, you can write R cells in a notebook. Or Julia. **Or all three!**
Quarto is a **separate tool** that runs in the shell. It comes with everything you need, except the programming languages you want to use.
:::
![](images/notebook-vs-document.png){fig-alt="A picture of the same Quarto document side-by-side, written in notebook form on the left and document form on the right." style="width:100%; height:auto;"}
## Editors {.text-indigo-pink style="text-align: center"}
::: {.notes}
The examples I've shown are in Visual Studio Code, which is a code editor that I love.
Quarto works really nicely there. It even has a help panel that switches languages as you type!
Quarto also works fantastically with the JupyterLab editor and with RStudio.
:::
:::: {.columns style="margin-top:150px;"}
::: {.column width="33%"}
[![](images/editor-vscode.png){fig-alt="Visual Studio Code logo" width="250px"}](https://code.visualstudio.com)
:::
::: {.column width="33%"}
[![](images/editor-rstudio.png){fig-alt="RStudio logo" width="250px"}](https://rstudio.com)
:::
::: {.column width="33%"}
[![](images/editor-jupyterlab.png){fig-alt="Jupyter logo" width="250px"}](https://jupyterlab.readthedocs.io/en/stable)
:::
::::
## RStudio visual editor {.text-indigo-pink style="text-align: center"}
::: {.notes}
If you use RStudio and you're used to writing documents but like the way notebooks look, you don't even have to choose!
RStudio has a **notebook-style editor** _for documents_.
You can switch back and forth as you like, and it has a command palette to help you insert things.
R Markdown has been able to include code from other languages for a while, but I think this is a really big step to facilitating cross-language collaboration.
For someone who only works in Python or Julia, it's a really tough sell to ask them to install R and several packages in order to write documents.
With Quarto, you can have a website with people contributing posts as a mix of notebooks and documents in any (or all languages).
:::
:::: {.columns}
::: {.column width="50%"}
![](images/rstudio-source.png){fig-alt="Editing a Quarto document in RStudio in the plain text view."}
:::
::: {.column width="50%"}
![](images/rstudio-visual.png){fig-alt="Editing a Quarto document in RStudio in the visual editor"}
:::
::::
# [Spicing up Quarto<br>[with [reactivity]{.hl .hl-red} and [Observable JS]{.hl .hl-red}]{style="font-size:75%;"}]{style="color:white"} { background="linear-gradient(45deg, #ed213a, #93291e)"}
::: {.notes}
Quarto has one other big feature that I think we need to talk about
It's called **Observable JS**, and it can make your reports, your books and your slides **reactive**.
:::
##
::: {.notes}
So when we render our document, code runs and it changes how the report looks.
Maybe it creates a plot from some data, or prints some statistics.
But sometimes we want our document to change **as it's being read.**
We want to let users to make decisions and for the document to **react** to things changing.
:::
::: {style="margin-top:-100px"}
### Reactivity? {.r-fit-text .text-orange-gold}
### HUH? {.r-fit-text .text-red-brown style="font-weight:900"}
:::
## Example: footy scores {.text-red-brown .center .smaller style="text-align:center"}
::: {.notes}
So let's say we had data on footy scores for different teams over a number of years.
We could try to make one graphic that shows all the data, but it's a lot!
And maybe different readers care about different teams.
We can let our chart **react** to the decisions our users make about footy team and year.
:::
**menu** + **slider** => **chart of footy scores**
::::: {.columns .fragment}
:::: {.column width="40%"}
::: {style="color:black"}
```{ojs}
//| echo: false
viewof footyTeam2 = Inputs.select(
["Pies", "Blues", "Bombers", "Cats"],
{ value: "Blues", label: "Footy team" })
viewof year2 = Inputs.range([1990, 2005],
{ value: 1990, step: 1, label: "Year", width: 300 })
```
:::
::::
:::: {.column width="60%"}
```{ojs}
//| echo: false
scores2 = FileAttachment("data/footy-scores.csv").csv({ typed: true })
filteredScores2 = scores.filter(d => d.team == footyTeam2 && d.year == year2)
Plot.plot({
marks: [
Plot.barY(filteredScores2, { x: "game", y: "score", fill: "game" })
],
x: { label: "Game number", labelOffset: 70 },
y: { label: "Score" },
width: 800,
height: 500,
marginLeft: 60,
marginBottom: 90,
marginTop: 60,
style: {
fontSize: 24
}
})
```
::::
:::::
## Code is usually about [doing things]{.hl .hl-red} {.text-red-brown .center style="text-align:center"}
::: {.notes}
Programs and websites do this all the time! There's a user interface with buttons and dials and sliders, and when we play with them, stuff happens.
But making that happen can be really tiring.
Web and app developers deal with this all the time:
* write code to create the button
* then write code to check its value all the time
* then write code to do things every time it changes
That's powerful, but it gets old really quickly!
:::
::::: {.columns}
:::: {.column width="50%"}
::: {.incremental}
* Write code to **create a control**
* Write code to **check its value all the time**
* Write code to **do things every time it changes**
* Write code to **pass updates from one thing to another**
:::
::::
:::: {.column width="50%"}
::: {.fragment}
<h2 class="text-orange-gold">This gets old quickly!</h2>
### π© {style="font-size:600%"}
:::
::::
:::::
## Reactive code just updates itself {.text-red-brown .center style="text-align:center"}
::: {.fragment}
Describe a control or input
:::
::: {.fragment}
Describe an output that **reacts** to the control's changes
:::
::: {.fragment}
... there is no step 3
<span style="font-size:smaller">(the output takes care of itself!)</span>
:::
## This is how [Shiny]{.hl .hl-red} and [Dash]{.hl .hl-red} work! {.text-red-brown style="text-align:center"}
**menu** + **slider** => **chart of footy scores**
::::: {.columns}
:::: {.column width="50%"}
::: {.fragment}
```{r}
#| eval: false
#| echo: true
#| code-line-numbers: "|6,11,13"
# describe some controls - a dropdown menu
# and a slider - and a plot
ui <- fluidPage(
selectInput("footyTeam",
label = "Footy team",
choices = c("Pies", "Blues",
"Bombers", "Cats"),
selected = "Blues"),
sliderInput("year", label = "Year",
1990, 2005, value = 1991),
plotOutput("footyScores")
)
```
:::
::::
:::: {.column width="50%"}
::: {.fragment}
```{r}
#| eval: false
#| echo: true
#| code-line-numbers: "|8,9,10"
# for the plot, filter our data and
# draw a line chart
server <- function(input, out) {
output$footyScores <- renderPlot({
scores %>%
filter(
year == input$year,
house == input$footyTeam) %>%
{
ggplot(.) +
aes(x = game, y = score) +
geom_line()
}
})}
```
:::
::::
:::::
## So why not use [Shiny?]{.hl .hl-red} {.text-red-brown .center style="text-align:center"}
::: {.notes}
(ref. slides)
Services like **shinyapps.io** serve websites to people, but they leave a copy of R running to allow things to react like this
:::
[Shiny already works with R Markdown, and it works with Quarto too]{.fragment}
[But you need R running to react to things **as people read the document**, not just when you render it]{.fragment}
[This requires a special web server! (eg. [shinyapps.io](https://shinyapps.io))]{.fragment}
## So why not use [Shiny?]{.hl .hl-red} {.text-red-brown .center style="text-align:center"}
::: {.notes}
(ref. slides)
My use is different to many of yours!
If you want to make something to be used internally, or by special stakeholders, Shiny is great!
:::
In media, charts could be viewed 100k+ times in days
[(If I'm lucky...)]{style="font-size:smaller"}
I can't afford a Shiny server for that kind of traffic!
## Enter [Observable JS]{.hl .hl-red} {.text-red-brown .center}
Quarto gives us a new kind of code chunk called [**OJS**]{.hl .hl-red}
It lets us write JavaScript that is **naturally reactive**
## Observable JS: no server required {.text-red-brown .center}
::::: {.columns}
:::: {.column width="50%"}
::: {.fragment}
We make a slider called `x`...
::: {style="color: black"}
```{ojs}
//| echo: true
viewof x = Inputs.range(
[0, 100], { step: 1 })
```
:::
:::
::::
:::: {.column width="50%"}
::: {.fragment}
... and then reference it:
```{ojs}
//| echo: true
md`The square of ${x} is ${x**2}!
How about that!`
```
:::
::: {.fragment}
The text **reacts** to the changing value of `x`. Nice!
:::
::::
:::::
## Footy example with Quarto + OJS {.text-red-brown .center .smaller}
::::: {.columns}
:::: {.column width="40%"}
::: {.panel-tabset}
### Plot
```{ojs}
//| echo: false
viewof footyTeam = Inputs.select(
["Pies", "Blues", "Bombers", "Cats"],
{ value: "Blues", label: "Footy team" })
viewof year = Inputs.range([1990, 2005],
{ value: 1990, step: 1, label: "Year", width: 300 })
```
### Code
```{ojs}
//| eval: false
//| echo: true
viewof footyTeam = Inputs.select(
["Pies", "Blues", "Bombers", "Cats"],
{ value: "Blues", label: "Footy team" })
viewof year = Inputs.range(
[1990, 2005],
{
value: 1990,
step: 1, label: "Year",
width: 300
})
```
:::
::::
:::: {.column width="60%"}
::: {.panel-tabset}
### Plot
```{ojs}
//| echo: false
scores = FileAttachment("data/footy-scores.csv").csv({ typed: true })
filteredScores = scores.filter(d => d.team == footyTeam && d.year == year)
Plot.plot({
marks: [
Plot.barY(filteredScores, { x: "game", y: "score", fill: "game" })
],
x: { label: "Game number", labelOffset: 70 },
y: { label: "Score" },
width: 800,
height: 500,
marginLeft: 60,
marginBottom: 90,
marginTop: 60,
style: {
fontSize: 24
}
})
```
### Code
```{ojs}
//| eval: false
//| echo: true
// load the data
scores = FileAttachment("data/footy-scores.csv")
.csv({ typed: true })
// filter it using the controls
filteredScores = scores.filter(
d => d.team == footyTeam &&
d.year == year)
// make the chart
Plot.plot({
marks: [
Plot.barY(filteredScores, {
x: "game",
y: "score",
fill: "game"
})
],
x: {
label: "Game number",
labelOffset: 70
},
y: { label: "Score" },
width: 800,
height: 500,
marginLeft: 60,
marginBottom: 90,
marginTop: 60,
style: { fontSize: 24 }
})
```
:::
::::
:::::
## {.text-red-brown .center}
::: {.notes}
This is really powerful. If we don't need a special server to make charts that react to users, they can be as popular as we like!
I can put Quarto documents on GitHub Pages, Netlify, or even Cloudflare Pages, which has **unlimited bandwidth**.
:::
::::: {.columns}
:::: {.column width="45%"}
### Quarto + {.r-fit-text}
### OJS means {.r-fit-text}
::::
:::: {.column width="10%"}
::::
:::: {.column width="45%"}
::: {.incremental}
* You can do your data analysis in R, Python or Julia
* You can make visuals that **react to users**
* You don't need to worry about the cost if it gets popular
* Learning JavaScript is as easy as possible
:::
::::
:::::
## {.text-red-brown}
::::: {.columns}
:::: {.column width="50%"}
### R/Python Widgets
"Web content" in R Markdown usually involves a special R or Python package (eg. [`htmlwidgets`](https://htmlwidgets.org))
π Convenient
π Customising means learning JavaScript _and_ learning how an R package works
::::
:::: {.column width="50%"}
### Quarto + OJS
It's just JavaScript!
You get great libraries bundled in to try out JS:
* Observable Plot for making charts
* Observable Inputs for making controls
* Arquero for data analysis (it's just like `dplyr`)
::::
:::::
## Seriously, _just_ like `dplyr`, I'm not even kidding {.text-red-brown .center}
::: {.notes}
Remember our survey before? That was doing data analysis on-the-fly with Arquero.
(click)
These are basically `dplyr` or `pandas` verbs!
:::
::::: {.columns}
:::: {.column width="40%"}
Remember the survey before?
I did that with **Observable Plot** and **Arquero**.
Here's the code I used to tally up survey responses:
::::
:::: {.column width="60%"}
::: {.fragment}
```{ojs}
//| eval: false
//| echo: true
countsUsed = aq.from(surveyResults)
.derive({
used: d => op.split(d.responseUsed, ", ")
})
.select("used")
.unroll("used")
.groupby("used")
.count()
.derive({ measure: d => "Have used" })
.rename({ used: "tool" })
```
:::
::::
:::::
## Use the whole web {.text-red-brown}
::: {.notes}
And when you're ready, you can use any other JavaScript library
(click to see)
This was a chart we built recently showing that many commercial satellites are used by governments and the military too.
(click to Italy)
This uses the `d3-euler` library, as well as a popup library called `micromodal`.
There's a lot we could do to improve this, but the actual JavaScript being used here would look very familar to an R or Python user!
This isn't much more complex than the dropdown menu and footy score chart
:::
::: {.fragment}
<iframe src="https://360info-satellitemixeduse.pages.dev/embed-user-overlaps" height="600" width="1400" style="background:white"></iframe>
:::
# Conclusions {.text-black-white background="linear-gradient(45deg, #fff, #666)"}
::: {.notes}
So we've seen these two major features of Quarto and how they make it stand out from R Markdown
:::
## Quarto helps you write documents... {.center }
... whether you use **R**, **Python** or **Julia**
... whether you like **notebooks** or **documents**
... whether you write in a **code editor** or a **notebook editor**
## Quarto help you make documents that react to users {.center}
... and you might learn JavaScript by accident!
::: {.notes}
Between these two features, I think Quarto has a really powerful funnel effect
Learning a new language or framework is a _big commitment_.
Do you try to learn something on the weekend, hope you stay motivated and that you'll have the time on top of the rest of your life?
Or do you take a risk and try to build something for work using a language you don't know?
It's taken me years to start using d3.js for exactly this reason
Quarto makes JavaScript and web visualisation accessible by inches, no matter which data science language you're coming from
:::
## A checklist for trying Quarto {.center}
π΄ Download Quarto from [quarto.org](https://quarto.org) and have a look at the [Guide](https://quarto.org/docs/guide)
π Try to render an existing R Markdown document or Jupyter notebook using Quarto and your favourite editor
π’ Switch out one of your charts for an [Observable Plot](https://observablehq.com/@observablehq/plot) chart
π΅ Try switching some `dplyr` or `pandas` verbs for some [Arquero verbs](https://observablehq.com/@uwdata/introducing-arquero)
π£ Try adding something to your document by importing an [Observable notebook](https://quarto.org/docs/interactive/ojs/libraries.html) or a [JavaScript library](https://quarto.org/docs/interactive/ojs/libraries.html)
# Thanks for listening!
Questions?
[**@jimjam-slam**](https://twitter.com/jimjam-slam)
[**360info.org**](https://360info.org)
[**github.com/360-info**](https://github.com/360-info)