diff --git a/boxplots_violins.Rmd b/boxplots_violins.Rmd index d91a918c..2234ed11 100644 --- a/boxplots_violins.Rmd +++ b/boxplots_violins.Rmd @@ -21,19 +21,24 @@ The simplest approach to showing many distributions at once is to show their mea (ref:lincoln-temp-points-errorbars) Mean daily temperatures in Lincoln, Nebraska in 2016. Points represent the average daily mean temperatures for each month, averaged over all days of the month, and error bars represent twice the standard deviation of the daily mean temperatures within each month. ```{r lincoln-temp-points-errorbars, fig.cap = '(ref:lincoln-temp-points-errorbars)'} -lincoln_weather %>% mutate(month_short = fct_recode(Month, - Jan = "January", - Feb = "February", - Mar = "March", - Apr = "April", - May = "May", - Jun = "June", - Jul = "July", - Aug = "August", - Sep = "September", - Oct = "October", - Nov = "November", - Dec = "December")) %>% +lincoln_weather %>% + mutate( + month_short = fct_recode( + Month, + Jan = "January", + Feb = "February", + Mar = "March", + Apr = "April", + May = "May", + Jun = "June", + Jul = "July", + Aug = "August", + Sep = "September", + Oct = "October", + Nov = "November", + Dec = "December" + ) + ) %>% mutate(month_short = fct_rev(month_short)) -> lincoln_df diff --git a/figures/iris.pdf b/figures/iris.pdf deleted file mode 100644 index bae40d21..00000000 Binary files a/figures/iris.pdf and /dev/null differ diff --git a/figures/iris.png b/figures/iris.png deleted file mode 100644 index 8fbb170f..00000000 Binary files a/figures/iris.png and /dev/null differ diff --git a/figures/iris_pdf_crops.idraw b/figures/iris_pdf_crops.idraw deleted file mode 100644 index 0967336d..00000000 Binary files a/figures/iris_pdf_crops.idraw and /dev/null differ diff --git a/figures/iris_png_crops.idraw b/figures/iris_png_crops.idraw deleted file mode 100644 index 42529d96..00000000 Binary files a/figures/iris_png_crops.idraw and /dev/null differ diff --git a/figures/iris_with_box.idraw b/figures/iris_with_box.idraw deleted file mode 100644 index 7e0cf49d..00000000 Binary files a/figures/iris_with_box.idraw and /dev/null differ diff --git a/figures/iris_with_box.pdf b/figures/iris_with_box.pdf deleted file mode 100644 index f9bdbbaa..00000000 Binary files a/figures/iris_with_box.pdf and /dev/null differ diff --git a/figures/iris_zoom.idraw b/figures/iris_zoom.idraw deleted file mode 100644 index 3097cd8a..00000000 Binary files a/figures/iris_zoom.idraw and /dev/null differ diff --git a/figures/iris_zoom.pdf b/figures/iris_zoom.pdf deleted file mode 100644 index f5e572b7..00000000 Binary files a/figures/iris_zoom.pdf and /dev/null differ diff --git a/figures/iris_zoom.png b/figures/iris_zoom.png deleted file mode 100644 index 2958af58..00000000 Binary files a/figures/iris_zoom.png and /dev/null differ diff --git a/figures/jpeg_example_combined.idraw b/figures/jpeg_example_combined.idraw index c8800642..36dc7d03 100644 Binary files a/figures/jpeg_example_combined.idraw and b/figures/jpeg_example_combined.idraw differ diff --git a/figures/jpeg_example_combined.jpg b/figures/jpeg_example_combined.jpg deleted file mode 100644 index 6d551e51..00000000 Binary files a/figures/jpeg_example_combined.jpg and /dev/null differ diff --git a/figures/jpeg_example_combined.pdf b/figures/jpeg_example_combined.pdf index 5936b081..13f58a93 100644 Binary files a/figures/jpeg_example_combined.pdf and b/figures/jpeg_example_combined.pdf differ diff --git a/figures/jpeg_example_combined.png b/figures/jpeg_example_combined.png new file mode 100644 index 00000000..05b2d59b Binary files /dev/null and b/figures/jpeg_example_combined.png differ diff --git a/figures/lincoln-temps.png b/figures/lincoln-temps.png new file mode 100644 index 00000000..ec5ff10b Binary files /dev/null and b/figures/lincoln-temps.png differ diff --git a/image_file_formats.Rmd b/image_file_formats.Rmd index 6ea973ca..b4b5f081 100644 --- a/image_file_formats.Rmd +++ b/image_file_formats.Rmd @@ -28,13 +28,121 @@ tiff Tagged Image File Format bitmap print production, accur raw Raw Image File bitmap digital photography, needs post-processing gif Graphics Interchange Format bitmap outdated, do not use -Vector graphics are also called "resolution-independent," because they can be magnified to arbitrary size without losing detail or sharpness. See Figure \@ref(fig:iris-zoom) for a demonstration. +Vector graphics are also called "resolution-independent," because they can be magnified to arbitrary size without losing detail or sharpness. See Figure \@ref(fig:bitmap-zoom) for a demonstration. + +(ref:bitmap-zoom) Illustration of the key difference between vector graphics and bitmaps. (a) Original image. The black square indicates the area we are magnifying in parts (b) and (c). (b) Increasing magnification of the highlighted area from part (a) when the image has been stored as a bitmap graphic. We can see how the image becomes increasingly pixelated as we zoom in further. (c) Increasing magnification of a vector representation of the image. The image maintains perfect sharpness at arbitrary magnification levels. + +```{r bitmap-zoom, fig.width = 8.5, fig.asp = 1/2.8, fig.cap='(ref:bitmap-zoom)'} +library(magick) + +# support functions --------------------------------------------------------- + +# cut square out of larger image +# x and y are center coordinates +cut_npc_square <- function(img, x, y, w) { + info <- magick::image_info(img) + width <- w*info$width + + xpx <- x*info$width - 0.5*width + ypx <- (1-y)*info$height-0.5*width # reverse coordinate system + + image_crop(img, geometry_area(width = width, height = width, x_off = xpx, y_off = ypx)) +} + +# add an image to a plot +# x and y are center coordinates, height is calculated from image aspect ratio +add_image <- function(img, x, y, width = NULL, interpolate = TRUE) { + info <- magick::image_info(img) + if (is.null(width)) { + width <- info$width + } + height <- width*info$height/info$width + x <- x - 0.5*width + y <- y - 0.5*height + draw_image(img, x, y, width, height, interpolate = interpolate) +} + +# adds a box corresponding to the size of an image +# x and y are center coordinates +add_image_box <- function(img, x, y, width = NULL) { + info <- image_info(img) + if (is.null(width)) { + width <- info$width + } + height <- width*info$height/info$width + geom_rect( + data = data.frame( + xmin = x - 0.5*width, xmax = x + 0.5*width, + ymin = y - 0.5*height, ymax = y + 0.5*height + ), + aes(xmin = xmin, xmax = xmax, ymin = ymin, ymax = ymax), + fill = NA, + color = "black" + ) +} + +# image drawing code --------------------------------------------------------- + +img_hires <- image_read("figures/lincoln-temps.png") +xc <- 0.73 # relative x center +yc <- 0.58 # relative y center +bw <- 0.16 # relative box width + +img <- image_scale(img_hires, "1800") +c5 <- cut_npc_square(img, xc, yc, bw) +img <- image_scale(img_hires, "3600") +c6 <- cut_npc_square(img, xc, yc, bw/2) +img <- image_scale(img_hires, "7200") +c7 <- cut_npc_square(img, xc, yc, bw/4) +c8 <- cut_npc_square(img_hires, xc, yc, bw/8) + +img <- image_scale(img_hires, "1200") +c1 <- cut_npc_square(img, xc, yc, bw) +c2 <- cut_npc_square(img, xc, yc, bw/2) +c3 <- cut_npc_square(img, xc, yc, bw/4) +c4 <- cut_npc_square(img, xc, yc, bw/8) + +info <- image_info(img) +p1 <- ggplot() + + expand_limits( + x = c(0, info$width-1), + y = c(-0.3*info$height, info$height-1) # add 30% vertical space below + ) + + coord_fixed(expand = FALSE) + + draw_image(img, x = 0, y = 0, width = info$width, height = info$height) + + add_image_box(c1, xc*info$width, yc*info$height, width = bw*info$width) + + theme_nothing() + +p2 <- ggplot() + + expand_limits(x = c(-0.01, 4.61), y = c(-0.01, 1.01)) + + coord_fixed(expand = FALSE) + + add_image(c1, x = 0.5, y = 0.5, width = 1, interpolate = FALSE) + + add_image(c2, x = 1.7, y = 0.5, width = 1, interpolate = FALSE) + + add_image(c3, x = 2.9, y = 0.5, width = 1, interpolate = FALSE) + + add_image(c4, x = 4.1, y = 0.5, width = 1, interpolate = FALSE) + + add_image_box(c1, x = 0.5, y = 0.5, width = 1) + + add_image_box(c2, x = 1.7, y = 0.5, width = 1) + + add_image_box(c3, x = 2.9, y = 0.5, width = 1) + + add_image_box(c4, x = 4.1, y = 0.5, width = 1) + + theme_nothing() + +p3 <- ggplot() + + expand_limits(x = c(-0.01, 4.61), y = c(-0.01, 1.01)) + + coord_fixed(expand = FALSE) + + add_image(c5, x = 0.5, y = 0.5, width = 1) + + add_image(c6, x = 1.7, y = 0.5, width = 1) + + add_image(c7, x = 2.9, y = 0.5, width = 1) + + add_image(c8, x = 4.1, y = 0.5, width = 1) + + add_image_box(c5, x = 0.5, y = 0.5, width = 1) + + add_image_box(c6, x = 1.7, y = 0.5, width = 1) + + add_image_box(c7, x = 2.9, y = 0.5, width = 1) + + add_image_box(c8, x = 4.1, y = 0.5, width = 1) + + theme_nothing() + +col <- plot_grid(p2, p3, labels = c("b", "c"), ncol = 1) +plot_grid(p1, col, labels = c("a", ""), nrow = 1, rel_widths = c(1, 1.5)) -(ref:iris-zoom) Illustration of the key difference between vector graphics and bitmaps. (a) Original image. The black square around the number seven indicates the area we're magnifying in parts (b) and (c). (b) Increasing magnification of the highlighted area from part (a) when the image has been stored as a bitmap graphic. We can see how the image becomes increasingly pixelated and blurry as we zoom in further. (c) Increasing magnification of a vector representation of the image. The image maintains perfect sharpness at arbitrary magnification levels. - -```{r iris-zoom, fig.cap='(ref:iris-zoom)'} -knitr::include_graphics("figures/iris_zoom.png") ``` Vector graphics have two downsides that can and often do cause trouble in real-world applications. First, because vector graphics are redrawn on the fly by the graphics program with which they are displayed, it can happen that there are differences in how the same graphic looks in two different programs, or on two different computers. This problem occurs most frequently with text, for example when the required font is not available and the rendering software substitutes a different font. Font substitutions will typically allow the viewer to read the text as intended, but the resulting image rarely looks good. There are ways to avoid these problems, such as outlining or embedding all fonts in a pdf file, but they may require special software and/or special technical knowledge to achieve. By contrast, bitmap images will always look correct. @@ -52,10 +160,10 @@ Photographic images rarely have multiple pixels of identical color and brightnes The most widely used lossy image format is jpeg (Table \@ref(tab:file-formats)), and indeed many digital cameras output images as jpeg by default. Jpeg compression works exceptionally well for photographic images, and huge reductions in file size can often be obtained with very little degradation in image quality. However, jpeg compression fails when images contain sharp edges, such as created by line drawings or by text. In those cases, jpeg compression can result in very noticeable artifacts (Figure \@ref(fig:jpeg-example)). -(ref:jpeg-example) Illustration of jpeg artifacts. (a) The same image is reproduced multiple times using increasingly severe jpeg compression. The resulting file size is shown in the top-right corner of each image. A reduction in file size by a factor of 10, from 432kB in the original image to 43kB in the compressed image, results in only minor perceptible reduction in image quality. However, a further reduction in file size by a factor of 2, to a mere 25kB, leads to numerous visible artifacts. (b) Zooming in to the most highly compressed image reveals the various compression artifacts. *Image credit: Claus O. Wilke* +(ref:jpeg-example) Illustration of jpeg artifacts. (a) The same image is reproduced multiple times using increasingly severe jpeg compression. The resulting file size is shown in red text above each image. A reduction in file size by a factor of 10, from 432kB in the original image to 43kB in the compressed image, results in only minor perceptible reduction in image quality. However, a further reduction in file size by a factor of 2, to a mere 25kB, leads to numerous visible artifacts. (b) Zooming in to the most highly compressed image reveals the various compression artifacts. *Image credit: Claus O. Wilke* ```{r jpeg-example, fig.cap='(ref:jpeg-example)'} -knitr::include_graphics("figures/jpeg_example_combined.jpg", dpi=600) +knitr::include_graphics("figures/jpeg_example_combined.png", dpi=210) ``` Even if jpeg artifacts are sufficiently subtle that they are not immediately visible to the naked eye they can cause trouble, for example in print production. Therefore, it is a good idea to avoid the jpeg format whenever possible. In particular, you should avoid it for images containing line drawings or text, as is the case for data visualizations or screen shots. The appropriate format for those images is png or tiff. I use the jpeg format exclusively for photographic images. And if an image contains both photographic elements and line drawings or text, you should still use png or tiff. The worst case scenario with those file formats is that your image files grow large, whereas the worst case scenario with jpeg is that your final product looks ugly.