Savefig() in Plots.jl is slow when I scatter 13056 points

I wish this was just an issue only caused by large datasets. On Plots.jl version 1.20.0, just 10 scatter points and a straight line drawn based on the parameters returned by LsqFit.jl seems to be extremely slow, regardless of the output format:

 8.972615 seconds (20.30 M allocations: 1.104 GiB, 4.26% gc time, 2.74% compilation time)

The code that generates these numbers goes as follows:

function draw_scatter_and_line(
    xdata,
    ydata,
    gradient,
    constant_term,
    scatter_title,
    line_title,
    xlabel,
    ylabel,
    filename
)
    img_path = joinpath(@__DIR__, filename)
    
    # Generate plot object
    img = Plots.plot(
        xlabel=xlabel,
        ylabel=ylabel,
        legend=:bottomright)

    # Measurements
    Plots.scatter!(
        img,
        xdata,
        ydata,
        label=scatter_title,
        color=:steelblue)

    # Generate fit
    fit_x = [xdata[begin] - abs(xdata[end] / 10), xdata[end] + xdata[end] / 10)
    fit_y = gradient .* fit_x .+ constant_term

    # Draw fitted line:
    Plots.plot!(
        img,
        fit_x,
        fit_y,
        linestyle=:dash,
        label=line_title,
        color=:steelblue)

    # The bottleneck    
    @time Plots.pdf(img, img_path)
end

The compilation times of Plots.{pdf, savefig} seem irrelevant when looking at how many allocations they are doing. Again, xdata and ydata are vectors of length 10…

1 Like

The allocations may also happen during compilation, they’re also counted towards the total allocation amount during the timed section.

I guess this is why it is generally recommended to use more robust benchmarking tools. Regardless, even during a second run there are roughly 250k allocations made by Plots.savefig alone, in the case of the mentioned 10 data points.