Я пытаюсь построить возрастную пирамиду в R, используяploty, и я также хочу добавить список раскрывающегося меню, чтобы фильтровать график по годам.
Вот код, который я использую:
dadosbr <- data.frame(
SEXO = sample(c("Masculino", "Feminino"), 7525, replace = TRUE),
FAIXA_ETARIA = sample(c("0-19", "20-29", "30-39", "40-49", "50-59", "60 ou mais"), 7525, replace = TRUE),
ANO_TRAT = sample(2019:2024, 7525, replace = TRUE))
sexo <- dadosbr %>%
group_by(SEXO, FAIXA_ETARIA, ANO_TRAT) %>%
tally() %>%
ungroup()
sexo <- sexo %>%
group_by(ANO_TRAT) %>%
mutate(percent = round(n / sum(n) * 100,1))
sexo <- sexo %>%
mutate(percent = ifelse(SEXO == "Feminino", -percent, percent))
plot_ly(sexo, hoverinfo = 'text', textposition = "none",
text = ~paste('</br> Ano do Início do Tratamento: ', ANO_TRAT,
'</br> Sexo: ', SEXO,
'</br> Número de Casos de TBDR: ', n,
'</br> %: ', percent)) %>%
add_trace(data = sexo[sexo$ANO_TRAT == 2019, ],
x = ~FAIXA_ETARIA, split = ~SEXO, y = ~n, type = 'bar', name = '2019', visible = TRUE) %>%
add_trace(data = sexo[sexo$ANO_TRAT == 2020, ],
x = ~FAIXA_ETARIA, split = ~SEXO, y = ~n, type = 'bar', name = '2020', visible = FALSE) %>%
add_trace(data = sexo[sexo$ANO_TRAT == 2021, ],
x = ~FAIXA_ETARIA, split = ~SEXO, y = ~n, type = 'bar', name = '2021', visible = FALSE) %>%
add_trace(data = sexo[sexo$ANO_TRAT == 2022, ],
x = ~FAIXA_ETARIA, split = ~SEXO, y = ~n, type = 'bar', name = '2022', visible = FALSE) %>%
add_trace(data = sexo[sexo$ANO_TRAT == 2023, ],
x = ~FAIXA_ETARIA, split = ~SEXO, y = ~n, type = 'bar', name = '2023', visible = FALSE) %>%
add_trace(data = sexo[sexo$ANO_TRAT == 2024, ],
x = ~FAIXA_ETARIA, split = ~SEXO, y = ~n, type = 'bar', name = '2024', visible = FALSE) %>%
layout(width = 820,
xaxis = list(title = "Raça/cor", linecolor = 'black', showline = TRUE, showgrid = FALSE),
yaxis = list(title = 'Número de Casos de TBR', showgrid = FALSE, zeroline = TRUE,
linecolor = 'black', range = c(0, 100)),
colorway = c("#4567a9", "#118dff", "#107dac", "#1ebbd7", "#064273", "#71c7ec"),
barmode = 'stack',
showlegend = FALSE,
updatemenus = list(
list(
active = 0,
buttons = list(
list(method = "restyle",
args = list("visible", list(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE)),
label = "2019"),
list(method = "restyle",
args = list("visible", list(FALSE, TRUE, FALSE, FALSE, FALSE, FALSE)),
label = "2020"),
list(method = "restyle",
args = list("visible", list(FALSE, FALSE, TRUE, FALSE, FALSE, FALSE)),
label = "2021"),
list(method = "restyle",
args = list("visible", list(FALSE, FALSE, FALSE, TRUE, FALSE, FALSE)),
label = "2022"),
list(method = "restyle",
args = list("visible", list(FALSE, FALSE, FALSE, FALSE, TRUE, FALSE)),
label = "2023"),
list(method = "restyle",
args = list("visible", list(FALSE, FALSE, FALSE, FALSE, FALSE, TRUE)),
label = "2024")
)
)
),
margin = list(l = 0, r = 0, b = 0, t = 0, pad = 0)
)
Я не знаю, что происходит не так. Я даже пытался переключить его на «стек», но это не сработало. Я хочу, чтобы результат был примерно таким:
Я сделал это с помощью ggplot, но не знаю, как это сделать с помощьюplotly.
Вот решение того, что вы спросили, исходя из того, что, я думаю, вы ищете. (Я использовал этот ответ Python, чтобы ответить на ваш вопрос в R.)
Использование данных в том виде, в котором вы их уже структурировали:
Я использовал set.seed(23)
для последовательного создания данных при работе над этим ответом (если вы хотели увидеть те же результаты).
Чтобы выровнять мужскую и женскую планку нужно barmode = "relative"
.
Чтобы создать горизонтальные полосы, в вызове plot_ly
добавьте orientation = "h"
.
xaxis
и yaxis
в вызове, на layout()
Чтобы контент, который вы назначили, text
наводил на контент (всплывающую подсказку), измените назначение с text =
на hovertext =
. (Поскольку вы установили textposition = "none"
, я предполагаю, что это была ваша цель... хотя на вашем изображении отображается текстовое содержимое... так что...)
x, y
, который отображается вверху каждой всплывающей подсказки, поскольку он является избыточным, назначьте его hovertemplate
вместо hovertext
или text
. Последнее изображение в этом ответе имеет это изменение. (Вы можете сравнить всплывающие подсказки на последних двух изображениях.)Я не уверен, какова была цель присвоения цветов. В вашем коде вы установили цвет для каждого года, но ваш идеал (основанный на изображении) имеет цвета, модерируемые по полу. Если вы использовали кнопки по годам, цвета по годам будут немного излишними. Вот пример того, как вы можете назначить цвета по полу, чтобы они соответствовали предоставленному вами визуальному элементу. Если вы хотите придерживаться цвета по годам, дайте мне знать, и я также добавлю информацию о том, как это сделать.
Я добавил код, чтобы сделать проценты, которые являются отрицательными для кодирования, положительными значениями.
ticktext
и tickvals
.hovertext =
добавлен abs()
, чтобы показать абсолютные значения. В противном случае этот контент соответствует исходному коду, присвоенному text =
. (Я также аннотировал это изменение в своих комментариях к коду.)Код, который вы присвоили
buttons =
, идентичен тому, который я создал с помощьюlst =
иlapply()
.
lst <- rep(F, length(unique(sexo$ANO_TRAT))) # visibility by trace
# create btns
btns <- lapply(1:length(lst), \(w) { # create buttons
lst[w] <- T # change one button's visibility
list(method = "restyle", label = sort(unique(sexo$ANO_TRAT))[w],
args = list("visible", lst))
})
# the plot
plot_ly(data = sexo, type = "bar", orientation = "h",
name = ~SEXO, color = ~SEXO, split = ~ANO_TRAT, # split traces by year
x = ~percent, y = ~FAIXA_ETARIA, # data to plot
# tooltip content
hovertext = ~paste('</br> Ano do Início do Tratamento: ', ANO_TRAT,
'</br> Sexo: ', SEXO,
'</br> Número de Casos de TBDR: ', n,
'</br> %: ', abs(percent))) %>% # <---- I added abs() here!
layout(xaxis = list(title = "Raça/cor",
tickmode = "array",
tickvals = seq(-10, 10, length.out = 5), # positive axis vals
ticktext = abs(seq(-10, 10, length.out = 5))),
# standoff = space btw title & labels
yaxis = list(title = list(text = 'Número de Casos de TBR', standoff = 20)),
barmode = "relative", # align the genders' bars horizontally
updatemenus = list(list(
pad = list(r = 55), # create space between graph & dropdown
showactive = T, # highlight visible trace's button
buttons = btns # from lapply
))) %>%
style(visible = F, traces = c(2:6, 8:12)) # set 2019 as only visible trace(s)
Если для кода подсказки установлено значение hovertemplate
вместо hovertext
или text
, это выглядит следующим образом:
Если у вас есть какие-либо вопросы или есть что-то еще, дайте мне знать.
Пробовали ли вы подход в Сюжет пирамиды в сюжете?