index.Rmd (5257B)
1 --- 2 title: "Web viewports" 3 author: "Eamon Caddigan" 4 date: "2023-08-21T21:07:47-07:00" 5 lastmod: "2023-08-22T08:58:51-07:00" 6 draft: False 7 categories: 8 - Programming 9 - Data Science 10 tags: 11 - Design 12 output: 13 md_document: 14 variant: markdown 15 preserve_yaml: true 16 --- 17 18 ```{r setup, include=FALSE} 19 knitr::opts_chunk$set(echo = FALSE, 20 fig.width = 5.5, 21 fig.height = 3, 22 dpi = 150, 23 fig.path = "") 24 ``` 25 26 Andy Bell from [Set Studio](https://set.studio/) shared [the outcome of a study 27 of browser viewport sizes](https://viewports.fyi/); the area of the screen 28 (measured in pixels) available for web pages. They shared the data so I thought 29 I'd take a quick look at it. 30 31 ```{r packages} 32 suppressPackageStartupMessages(library(readr)) 33 suppressPackageStartupMessages(library(dplyr)) 34 suppressPackageStartupMessages(library(purrr)) 35 suppressPackageStartupMessages(library(broom)) 36 suppressPackageStartupMessages(library(ggplot2)) 37 ``` 38 39 ```{r load-data, cache=TRUE} 40 viewports <- suppressMessages(read_csv("https://viewports.fyi/data.csv", 41 col_types = cols( 42 Width = col_double(), 43 Height = col_double(), 44 Count = col_double(), 45 ...4 = col_character() 46 ))) |> 47 mutate(Height = abs(Height), 48 aspect_ratio = Width / Height, 49 area = Width * Height) 50 ``` 51 52 First let's check the distribution of aspect ratios. With mobile browsing more 53 popular than desktop, I expect tall displays to dominate the wide ones, but what 54 do the data say? 55 56 ```{r plot-aspect-ratio, warning=FALSE} 57 ggplot(viewports, aes(aspect_ratio)) + 58 geom_density(aes(weight = Count)) + 59 scale_x_log10(breaks = c(1/3, 9/16, 1, 16/9, 3/1), 60 labels = c("1:3", "9:16", "1:1", "16:9", "3:1")) + 61 coord_cartesian(xlim = c(1/4, 4/1)) + 62 theme(panel.background = element_blank(), 63 panel.grid = element_blank(), 64 axis.text.y = element_blank(), 65 axis.ticks.y = element_blank(), 66 axis.title = element_blank(), 67 axis.text.x = element_text(size = 14), 68 axis.ticks.x = element_line(linewidth = 1), 69 plot.title = element_text(size = 16)) + 70 labs(title = "Distribution of viewport aspect ratios") 71 ``` 72 73 As expected, tall (narrow) displays dominate the distribution, bu the peak also 74 seems sharper. This isn't surprising; phone screens come in a few discrete 75 sizes, and for each phone screen, there is a small number of viewports (but, 76 importantly, more than one) associated with each one. 77 78 How do the distribution of height and width relate to each other? I'll plot a 79 point for each unique viewport, and set the alpha value of each point to the 80 number of observations of that specific size. Points above and to the left of 81 the dashed line are taller than they are wide (i.e., "portrait mode"), and those 82 below and to its right are wider than tall ("landscape mode"). We confirmed that 83 tall viewports are the most common by looking at aspect ratios, but how are the 84 specific sizes distributed? 85 86 ```{r plot-height-width} 87 ggplot(viewports, aes(x = Width, y = Height)) + 88 geom_point(aes(alpha = Count)) + 89 geom_abline(slope = 1, intercept = 0, linetype = "dashed", linewidth = 0.5) + 90 scale_x_log10() + 91 scale_y_log10() + 92 theme_minimal() + 93 theme(axis.title = element_text(size = 14), 94 axis.text = element_text(size = 12)) + 95 labs(x = "Viewport width", 96 y = "Viewport height") 97 ``` 98 99 I feel like my eye detects three clusters of height-by-width combinations, but 100 k-means is clustering these unreliably—sometimes the "small wide" viewports get 101 clustered alone together, and sometimes they're grouped with the "small tall" 102 viewports. This suggests that three (and also four—I checked) clusters don't 103 describe these data particularly well. 104 105 However, taking these two graphics together, we can see that while tall displays 106 tend to be smaller than wide ones in general (which is what we may expect, 107 knowing that mobile browsers are more prevalent than desktop browsers), there 108 are plenty of exceptions in the data set which should be considered during 109 design. 110 111 I think there's more to look at here, and I'll update this if I find anyting 112 interesting! 113 114 ```{r cluster-viewports, include=FALSE} 115 viewports_long <- viewports |> 116 mutate(log_width = log(Width), 117 log_height = log(Height)) |> 118 map_dfc(~ rep(.x, times = viewports$Count)) 119 viewports_clust <- kmeans(viewports_long[, c("Width", "Height")], 4) 120 viewports_long <- augment(viewports_clust, 121 viewports_long) 122 viewports <- distinct(viewports_long) 123 ``` 124 125 ```{r plot-clusters, include=FALSE} 126 ggplot(viewports_long, aes(Width, Height)) + 127 geom_point(aes(alpha = Count, color = .cluster)) + 128 geom_abline(slope = 1, intercept = 0, linetype = "dashed", linewidth = 0.5) + 129 scale_x_log10() + 130 scale_y_log10() + 131 scale_color_brewer(palette = "Paired") + 132 theme_minimal() + 133 theme(axis.title = element_text(size = 14), 134 axis.text = element_text(size = 12)) + 135 labs(x = "Viewport width", 136 y = "Viewport height") 137 ```