StatsPlots.jl prints out incomplete subplots

Hi

I used StatsPlots.jl to make a series of violin plots, but the final output seems cropped.
Here are the steps to reproduce the problem:

To create a similar data frame:

# create df
df = DataFrame(b = Int[], y =Float32[], a=String[], x=String[]) 
for k=[5, 10, 15, 20]
  for j = 1:100
    val1, val2, val3 = randn(3) .+ 0.5  # some calculations to generate val1, val2, val3
    push!(df, [k, val1, "High", "string1"])
    push!(df, [k, val2, "High", "string2"])
    push!(df, [k, val3, "High", "string3"])

    val1, val2, val3 = randn(3) .+ 0.5  # some other calculations to generate val1, val2, val3
    push!(df, [k, val1, "Low", "string1"])
    push!(df, [k, val2, "Low", "string2"])
    push!(df, [k, val3, "Low", "string3"])
  end
end

where the dataframe df looks like

 Row │ b        y            a           x        
         │ Int64  Float32  String    String       
─── ┼────────────────────────────────────────
    1   │     5    0.896  High        string1
    2   │     5    0.884  Low         string1
    3   │     5    0.828  High        string2
    4   │     5    0.518  Low         string2
    5   │     5    0.984  High        string3
    6   │     5    0.984  Low         string3
    7   │     5    0.982  High        string1
    8   │     5    0.98    Low         string1
    9   │     5    0.516  High        string2
   10  │     5    0.518  Low        string2
   11  │     10   0.744  High       string3
   12  │     10  0.734  Low        string3
   13  │     10  0.62    High       string1
   14  │     10  0.642  Low        string1
....

To make the subplots:

theme(:default)
p = []
for k = [5, 10, 15, 20]
    p1 = @df filter(row -> (row.a == "High") & (row.b == k), df) violin(:x, :y, 
        side=:left, linewidth=0, size=(800, 800),xtickfontsize=30,ytickfontsize=30,legendfont=font(24),
        palette =:Paired_8, label="High")
    @df filter(row -> (row.a == "High") & (row.b == k), df) dotplot!(p1, :x, :y, 
        side=:left, markersize=10, markerstrokewidth=0, palette =:Paired_8, label="")
    @df filter(row -> (row.a == "Low") & (row.b == k), df) violin!(p1, :x, :y, 
        side=:right, linewidth=0, 
        palette =:Pastel1_3, label="Low")
    @df filter(row -> (row.a == "Low") & (row.b == k), df) dotplot!(p1, :x, :y, 
        side=:right, markersize=10, markerstrokewidth=0, palette =:Paired_8, label="")
    ylims!(p1, (0.45,1.05))
    push!(p, p1)
end
plot(p..., layout=(1, 4), size=(4800, 1200))

While each individual plot looks okay, the final output was cropped:

where the x and y ticks were incomplete.

Any help would be much appreciated. What’s the possible cause of this? Is there a more idiomatic way of creating such a plot?

Thank you very much!

Try: using Measures and to add the following keywords to plot: left_margin=10mm, bottom_margin=10mm or just margin=10mm

4 Likes

It worked! Thank you!