Skip to content

Instantly share code, notes, and snippets.

@klmr
Created October 20, 2021 16:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save klmr/438538cccf54a9eac5778a85b9e59f90 to your computer and use it in GitHub Desktop.
Save klmr/438538cccf54a9eac5778a85b9e59f90 to your computer and use it in GitHub Desktop.
box::use(
dplyr[...],
glue[glue],
grid,
ld = lubridate,
ragg[...],
rvest,
scales[label_date_short, label_percent],
tidyr[...],
./screen_size[...],
klmr/ggplots[...],
)
# Number with optional decimals
num_re = r'(\d+(?:\.\d+)?)'
url = 'https://en.wikipedia.org/wiki/Comparison_of_Google_Pixel_smartphones'
html = rvest$read_html(url)
table = rvest$html_table(html)[[1L]] |>
rename(Var = 1L, Sub = 2L) |>
# Complicated nested rows, which we don’t need, thus remove them.
filter(! Var %in% c('Rear camera', 'Front camera')) |>
mutate(Var = ifelse(Var == Sub, Var, Sub)) |>
select(-Sub) |>
pivot_longer(-1L, names_to = 'Model') |>
pivot_wider(id_cols = Model, names_from = Var) |>
rename(Size = matches('^Size')) |>
extract(
Size,
into = c('W', 'H', 'D'),
glue('({num_re}).mm.×.({num_re}).mm.×.({num_re}).mm.*'),
convert = TRUE
) |>
extract(
Display,
into = c('Diagonal', 'AspA', 'AspB'),
glue(r'{[^)]+\((\d+).mm\).*?(\d+):(\d+).aspect ratio.*}'),
convert = TRUE
) |>
mutate(
Ratio = screen_to_body_ratio(Diagonal, AspA / AspB, W, H),
Released = ld$parse_date_time(Released, 'B Y')
)
simple_model = \(model) sub('(Pixel(?: \\d+)?).*', '\\1', model)
model_colors = setNames(
c('#4285F4', '#34A853', '#FBBC05', '#EA4335', '#EA8600', '#137333'),
unique(simple_model(table$Model))
)
x_ticks = unique(ld$round_date(table$Released, unit = 'year'))
# Simple gradient background
bg = grid$rasterGrob(
hcl(0, 0, seq(98, 92, by = -0.5)),
width = unit(1, 'npc'),
height = unit(1, 'npc'),
interpolate = TRUE
)
p = ggplot(table) +
aes(x = Released, y = Ratio) +
geom_smooth(method = lm, se = FALSE, color = 'gray') +
geom_point(aes(color = simple_model(Model)), size = 2) +
scale_x_datetime(breaks = x_ticks, labels = label_date_short()) +
scale_y_continuous(labels = label_percent()) +
scale_color_manual(values = model_colors) +
geom_text(
aes(label = sub('Pixel *(\\d+( |$))?', '', Model)),
hjust = 0,
nudge_x = 2000000,
color = '#808080',
size = 3
) +
labs(
x = 'Release date', y = '', color = '',
title = 'Screen-to-body ratio of Google Pixel phones',
caption = glue('Source: {url} (accessed on {ld$today()})')
) +
theme(
panel.grid.minor = element_blank(),
panel.grid.major = element_line(size = 0.5, color = 'white'),
plot.title.position = 'plot',
plot.caption.position = 'plot',
plot.caption = element_text(size = 6)
)
plot(p)
agg_png(
'pixel-screen-to-body-ratio.png',
width = 1920L, height = 1080L,
scaling = 4
)
grid$grid.newpage()
grid$grid.draw(bg)
plot(p, newpage = FALSE)
invisible(dev.off())
#' @export
screen_to_body_ratio = function (diagonal, aspect_ratio, w, h) {
body = w * h
screen = screen_area(diagonal, aspect_ratio)
screen / body
}
screen_area = function (diagonal, aspect_ratio) {
angle = atan(aspect_ratio)
w = cos(angle) * diagonal
h = sin(angle) * diagonal
w * h
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment