I want to make multi-panel plots in Pumas, but I am looking for something simple that can be reproduced by someone else on a different dataset. The dataframe can be thought of as having three columns: id, time, dv_ipred; where id is the faceting column, time is the x-axis and dv_ipred is the y-axis.
I looked at the AlgebraOfGraphics piece of code:
f = data(df) * mapping(:time, :dv_ipred, layout=:id => nonnumeric)
draw(f)
However, if there are any missing rows in dv_ipred it just prints the column out like a string in the plot even though it is type of Float64. AoG is very constrained and does not provide lot of flexibility.
So, I tried something in CairoMakie but the code (attached) got long very quickly. Would appreciate if you have any better ideas of doing this.
unique_subjects = unique(df.id)
num_subjects = length(unique_subjects)
num_columns = Int(ceil(sqrt(num_subjects)))
num_rows = Int(ceil(num_subjects/num_columns))
resolution = (1000,1000)
f = Figure(; resolution)
id_counter = 1
for (row, col) in Base.product(1:num_rows, 1:num_columns)
if id_counter <= num_subjects
a1 = Axis(f[row, col], title="ID = " * string(unique_subjects[id_counter]))
subject_df = filter(x -> x.id == unique_subjects[id_counter], df)
lines!(a1, subject_df.time, subject_df.dv_ipred, color=:black)
id_counter += 1
end
end
plottitle = Label(f[0, :], "PK Profiles", textsize = 30)
yaxis_lab = Label(f[:, 0], "Concentrations", rotation = pi/2, textsize=20)
xaxis_lab = Label(f[(num_rows+1):(num_rows+2), :], "Time", textsize=20,
padding = (0, 0, 0, resolution[1]/20))
f