I am having problems saving my plots in 300dpi. I have used a similar code before but now it is saving them in 96pdi
Here is a sample code (doesn't matter what type of plot it save it at the same resolution)
df <- data.frame(
Group = rep(c("A", "B", "C", "D"), each = 10),
Value = c(rnorm(10, mean = 5),
rnorm(10, mean = 7),
rnorm(10, mean = 6),
rnorm(10, mean = 8))
)
p <- ggplot(df, aes(x = Group, y = Value, fill = Group)) +
geom_boxplot() +
labs(title = "Test Boxplot", y = "Value", x = "Group") +
theme_minimal()
print(p)
ggsave("test_plot.jpg", plot = p, width = 150, height = 100, dpi = 300, units = "mm")
Could point me in the right direction of what could be the issue, because I have used a similar code before and had no problem
I can reproduce this on Windows if I right-click and look at the DPI in properties. It looks to me like ggplot2
is not writing out the DPI into the image metadata. It is a known issue in the 24H2 update of Windows 11, where it incorrectly reports that images without DPI metadata are 96 DPI. Similarly, as the metadata is missing, magick
will report the wrong number, that the density is 72x72
:
magick::image_read("test_plot.jpg") |>
magick::image_info()
# format width height colorspace matte filesize density
# <chr> <int> <int> <chr> <lgl> <int> <chr>
# 1 JPEG 1771 1181 sRGB FALSE 190568 72x72
As you can see, the image has dimension 1771x1181
. We can write a function to calculate the expected dimensions of the image at the desired DPI:
get_pixels_at_dpi <- function(width, height, dpi, mm_per_inch = 25.4) {
c(
width = floor(width / mm_per_inch * dpi),
height = floor(height / mm_per_inch * dpi)
)
}
You can see that the dimensions as reported by magick
are correct for 300 DPI:
get_pixels_at_dpi(width = 150, height = 100, dpi = 96)
# width height
# 566 377
get_pixels_at_dpi(width = 150, height = 100, dpi = 300)
# width height
# 1771 1181
And in case you don't believe magick
(as it was wrong about DPI), we can use another approach:
jpeg::readJPEG("test_plot.jpg", native = TRUE) |> dim()
# [1] 1181 1771
So it's just the metadata is incorrect - the image itself appears to be at the correct resolution for the desired DPI.
If you are submitting these images to a journal or elsewhere which might check the metadata to establish whether the image is the appropriate size, you can use magick
to fix it:
magick::image_read("test_plot.jpg") |>
magick::image_write("test_plot_fixed.jpg", density = "300x300")
Then if you read this back in (or right-click on Windows) you'll see it has the correct density:
magick::image_read("test_plot_fixed.jpg") |>
magick::image_info()
# format width height colorspace matte filesize density
# <chr> <int> <int> <chr> <lgl> <int> <chr>
# 1 JPEG 1771 1181 sRGB FALSE 68303 300x300