Skip to content

Commit 8fe4d77

Browse files
ajinkya-kpalday
andauthored
Moving R plots to julia (#92)
Co-authored-by: Phillip Alday <palday@users.noreply.github.com>
1 parent c5fddf5 commit 8fe4d77

File tree

11 files changed

+109
-57
lines changed

11 files changed

+109
-57
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ data/
1919
site_libs/
2020
/.quarto/
2121
/.luarc.json
22+
.cache/

Project.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ MixedModelsMakie = "b12ae82c-6730-437f-aff9-d2c38332a376"
2828
NLopt = "76087f3c-5699-56af-9a33-bf431cd00edd"
2929
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
3030
PooledArrays = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
31-
RCall = "6f49c342-dc21-5d91-9882-a32aef131414"
3231
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
3332
RectangularFullPacked = "27983f2f-6524-42ba-a408-2b5a31c238e4"
3433
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
@@ -62,7 +61,6 @@ MixedModels = "4,5"
6261
MixedModelsMakie = "0.4"
6362
NLopt = "1"
6463
PooledArrays = "1"
65-
RCall = "0.14.8"
6664
Random = "1"
6765
SHA = "0.7"
6866
Scratch = "1"
@@ -71,7 +69,7 @@ StatsAPI = "1"
7169
StatsBase = "0.33, 0.34"
7270
StatsModels = "0.7"
7371
Tables = "1"
74-
TidierPlots = "0.11"
72+
TidierPlots = "0.11.1"
7573
TypedTables = "1"
7674
ZipFile = "0.10"
7775
julia = "1.10"

aGHQ.qmd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ fig-height: 3
44
fig-dpi: 192
55
fig-format: png
66
engine: julia
7+
execute:
8+
cache: true
79
julia:
810
exeflags: ["--project"]
911
---

datatables.qmd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
---
22
engine: julia
3+
execute:
4+
cache: true
35
---
46

57
# Working with data tables {#sec-datatables}

glmmbernoulli.qmd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ fig-height: 3
44
fig-dpi: 192
55
fig-format: png
66
engine: julia
7+
execute:
8+
cache: true
79
julia:
810
exeflags: ["--project"]
911
---

intro.qmd

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ fig-height: 3
44
fig-dpi: 192
55
fig-format: png
66
engine: julia
7+
execute:
8+
cache: true
79
julia:
810
exeflags: ["--project"]
911
---
@@ -675,13 +677,6 @@ The apparent distribution of the estimates of $\sigma_1$ in @fig-dsm01_bs_sigma_
675677
A [kernel density estimate](https://en.wikipedia.org/wiki/Kernel_density_estimation) approximates a probability density from a finite sample by blurring or smearing the positions of the sample values according to a *kernel* such as a narrow Gaussian distribution (see the linked article for details).
676678
In this case the distribution of the estimates is a combination of a continuous distribution and a spike or point mass at zero as shown in a histogram, @fig-dsm01_bs_sigma_hist.
677679
678-
:::{.callout-note collapse="true"}
679-
680-
### Adjust the alpha in multiple histograms
681-
682-
Use a lower alpha in the colors for multiple histograms so the bars behind another color are more visible
683-
:::
684-
685680
```{julia}
686681
#| code-fold: true
687682
#| fig-cap: Histogram of bootstrap variance-components as standard deviations from model dsm01
@@ -693,7 +688,7 @@ draw(
693688
:value => "Bootstrap parameter estimates of σ";
694689
color=(:group => "Group"),
695690
) *
696-
AlgebraOfGraphics.histogram(; bins=80);
691+
AlgebraOfGraphics.histogram(; bins=80) * visual(alpha = 0.4);
697692
figure=(; size=(600, 340)),
698693
)
699694
```
@@ -724,7 +719,7 @@ draw(
724719
:value_abs2 => "Bootstrap sample of estimates of σ²",
725720
color=:group,
726721
) *
727-
AlgebraOfGraphics.histogram(; bins=200);
722+
AlgebraOfGraphics.histogram(; bins=200) * visual(alpha = 0.4);
728723
figure=(; size=(600, 340)),
729724
)
730725
```

largescaledesigned.qmd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ fig-height: 3
44
fig-dpi: 192
55
fig-format: png
66
engine: julia
7+
execute:
8+
cache: true
79
julia:
810
exeflags: ["--project"]
911
---

longitudinal.qmd

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ fig-height: 3
44
fig-dpi: 192
55
fig-format: png
66
engine: julia
7+
execute:
8+
cache: true
79
julia:
810
exeflags: ["--project"]
911
---
@@ -44,8 +46,8 @@ using LinearAlgebra
4446
using MixedModels
4547
using MixedModelsMakie
4648
using Random
47-
using RCall
4849
using StandardizedPredictors
50+
using Statistics
4951
```
5052

5153
and declare some constants, if not already defined.
@@ -96,7 +98,8 @@ draw(
9698
:resp => "Ramus bone length (mm)",
9799
color=:Subj,
98100
) *
99-
(visual(Scatter) + visual(Lines));
101+
(visual(Scatter) + visual(Lines)),
102+
scales(Color = (; legend = false,));
100103
figure=(; size=(600, 450)),
101104
)
102105
```
@@ -105,22 +108,48 @@ Unfortunately, unless there are very few subjects, such figures, sometimes calle
105108

106109
A preferred alternative is to plot response versus time with each subject's data in a separate panel (@fig-eglayout).
107110

108-
```{r}
111+
```{julia}
109112
#| code-fold: true
110113
#| fig-cap: Length of ramus bone versus age for a sample of 20 boys. The panels are ordered rowwise, starting at the bottom left, by increasing bone length at age 8.
111114
#| label: fig-eglayout
112-
plot(
113-
lattice::xyplot(
114-
resp ~ time|Subj,
115-
$egdf,
116-
type=c("g","p","r"),
117-
aspect="xy",
118-
index.cond=function(x,y) coef(lm(y ~ x)) %*% c(1,8),
119-
xlab="Age (yr)",
120-
ylab="Ramus bone length (mm)",
121-
)
115+
age_8 = subset(egdf, :time => ByRow(==(8)))
116+
sort!(age_8, :resp)
117+
slopes = combine(
118+
groupby(egdf, :Subj),
119+
:resp => std => :sy,
120+
:time => std => :sx,
121+
[:resp, :time] => ((a,b) -> cor(a, b)) => :corr,
122+
[:time, :resp] => ((x,y) -> cor(x, y) * std(y) / std(x)) => :slopeabs,
122123
)
123-
NULL
124+
125+
ry = maximum(egdf.resp) - minimum(egdf.resp)
126+
rx = maximum(egdf.time) - minimum(egdf.time)
127+
128+
α = median(slopes.slopeabs) * rx / ry
129+
130+
plt = data(egdf) *
131+
mapping(
132+
:time => "Age (yr)",
133+
:resp => "Ramus bone length (mm)",
134+
layout = :Subj => sorter(age_8.Subj),
135+
) * (visual(Scatter, marker = '∘', markersize = 20) + linear(; interval=nothing)) *
136+
visual(color = :blue)
137+
fg = draw(plt, scales(Layout = (; palette = vec([(b,a) for a in 1:10, b in 2:-1:1])));
138+
axis = (; aspect = α, xticklabelrotation = pi/2, xticklabelsize = 10),
139+
figure = (; size=(800, 600))
140+
);
141+
142+
f = fg.figure
143+
144+
colgap!(f.layout, 0);
145+
rowgap!(f.layout, 5);
146+
for col in 1:10
147+
print
148+
colsize!(f.layout, col, Aspect(1, α))
149+
end
150+
151+
152+
f
124153
```
125154

126155
To aid comparisons between subjects the axes are the same in every panel and the order of the panels is chosen systematically - in @fig-eglayout the order is by increasing bone length at 8 years of age.
@@ -170,7 +199,7 @@ If the purpose of the experiment is to create a predictive model for the growth
170199

171200
Alternatively, we could center at the average observed time, 8.75 years, or at some other value of interest.
172201

173-
The important thing is to make clear what the `(Itercept)` parameter estimates represent.
202+
The important thing is to make clear what the `(Intercept)` parameter estimates represent.
174203
The [StandardizedPredictors.jl](https://github.com/beacon-biosignals/StandardizedPredictors.jl) package allows for convenient representations of several standardizing transformations in a `contrasts` specification for the model.
175204
An advantage of this method of coding a transformation is that the coefficient names include a concise description of the transformation.
176205

@@ -336,8 +365,10 @@ draw(
336365
data(bxgdf[("Control",)]) *
337366
bxaxes *
338367
mapping(; color=:Subj) *
339-
(visual(Scatter) + visual(Lines));
368+
(visual(Scatter) + visual(Lines)),
369+
scales(Color = (; legend = false,));
340370
figure=(; size=(600, 450)),
371+
legend = (; position=:bottom, titleposition = :left)
341372
)
342373
```
343374

@@ -603,10 +634,12 @@ draw(
603634
data(@subset(bxm03pars, :type == "ρ")) *
604635
mapping(
605636
:value => "Bootstrap replicates of correlation estimates";
606-
color=(:names => "Variables"),
637+
color = :names => renamer(["(Intercept), time" => "(Intercept), time", "(Intercept), time ^ 2" => "(Intercept), time².", "time, time ^ 2" => "time, time²"]) => "Variables"
607638
) *
608-
AlgebraOfGraphics.density();
639+
AlgebraOfGraphics.density(),
640+
scales(Color = (; palette = [:tomato, :teal, :orange],));
609641
figure=(; size=(600, 400)),
642+
legend=(;position=:bottom, titleposition = :left)
610643
)
611644
```
612645

@@ -624,11 +657,13 @@ let
624657
)
625658
mp = mapping(
626659
:z => "Fisher's z transformation of correlation estimates";
627-
color=(:names => "Variables"),
660+
color=:names => renamer(["(Intercept), time" => "(Intercept), time", "(Intercept), time ^ 2" => "(Intercept), time².", "time, time ^ 2" => "time, time²"]) => "Variables"
628661
)
629662
draw(
630-
data(dat) * mp * AlgebraOfGraphics.density();
663+
data(dat) * mp * AlgebraOfGraphics.density(),
664+
scales(Color = (; palette = [:tomato, :teal, :orange],));
631665
figure=(; size=(600, 400)),
666+
legend=(;position=:bottom, titleposition = :left)
632667
)
633668
end
634669
```
@@ -723,8 +758,10 @@ let
723758
color=:Group,
724759
col=:model,
725760
) *
726-
visual(Lines);
727-
axis=(width=120, height=130),
761+
visual(Lines),
762+
scales(Color = (; palette = [:tomato, :teal, :orange],));
763+
figure=(; size=(600, 400)),
764+
legend=(;position=:bottom, titleposition = :left)
728765
)
729766
end
730767
```

multiple.qmd

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ fig-height: 3
44
fig-dpi: 192
55
fig-format: png
66
engine: julia
7+
execute:
8+
cache: true
79
julia:
810
exeflags: ["--project"]
911
---
@@ -45,7 +47,6 @@ using EmbraceUncertainty: dataset
4547
using MixedModels
4648
using MixedModelsMakie
4749
using Random
48-
using RCall
4950
using StatsBase
5051
```
5152

@@ -247,7 +248,7 @@ We say that "fill-in" has occurred when forming the sparse Cholesky decompositio
247248
In this case there is a relatively minor amount of fill but in other cases there can be a substantial amount of fill.
248249
The computational methods are tuned to reduce the amount of fill.
249250

250-
### Precision of parameter estimates in the Pencillin model {#sec-Penicillinprecision}
251+
### Precision of parameter estimates in the Penicillin model {#sec-Penicillinprecision}
251252

252253
A parametric bootstrap sample of the parameter estimates
253254

@@ -350,19 +351,40 @@ It would be fine to do this within a batch but the plot would be misleading if w
350351
There is no relationship between cask 'a' in batch 'A' and cask 'a' in batch 'B'.
351352
The labels 'a', 'b' and 'c' are used only to distinguish the three samples within a batch; they do not have a meaning across batches.
352353

353-
```{r}
354+
```{julia}
354355
#| code-fold: true
355356
#| fig-cap: "Strength of paste preparations according to sample within batch"
356357
#| label: fig-pastesdot
357-
pp <- within($pastes, bb <- reorder(batch, strength))
358-
plot(
359-
lattice::dotplot(sample ~ strength | bb, pp, pch = 21, strip = FALSE,
360-
strip.left = TRUE, layout = c(1, 10),
361-
scales = list(y = list(relation = "free")),
362-
ylab = "Sample within batch", type = c("p", "a"),
363-
xlab = "Paste strength", jitter.y = TRUE)
364-
)
365-
NULL
358+
batch_sort = sort!(combine(groupby(pastes, :batch),
359+
:strength => mean => :strength),
360+
:strength; rev=true).batch
361+
362+
paste_means = combine(groupby(pastes, [:cask, :batch]),
363+
:sample,
364+
:strength => mean => "strength" )
365+
366+
fg = draw(
367+
data(pastes) *
368+
mapping(
369+
:cask => "Cask within batch",
370+
:strength,
371+
col = :batch => sorter(batch_sort)
372+
) * visual(Scatter; marker = '∘', markersize = 15, color = :blue) +
373+
data(paste_means) *
374+
mapping(
375+
:cask => "Cask within batch",
376+
:strength,
377+
col = :batch => sorter(batch_sort)
378+
) * visual(Lines; color = :blue);
379+
# axis = (; xticklabelsize = 10),
380+
facet = (; linkyaxes=:minimal),
381+
figure = (; size=(700, 350))
382+
);
383+
384+
f = fg.figure
385+
386+
colgap!(f.layout, 4)
387+
f
366388
```
367389

368390
In @fig-pastesdot we plot the two strength measurements on each of the samples within each of the batches and join up the average strength for each sample.

references.qmd

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,5 @@ using Pkg
2626
Pkg.status()
2727
```
2828

29-
```{julia}
30-
#| echo: false
31-
using RCall
32-
```
33-
34-
```{r}
35-
print(sessionInfo())
36-
NULL
37-
```
3829

3930
*This page was rendered from git revision {{< git-rev short=true >}} using Quarto {{< version >}}.*

0 commit comments

Comments
 (0)