#r #ggplot2 #shiny #plotly #flexdashboard
Вопрос:
У меня проблема, когда значения по оси x (производители, перечисленные на тепловой карте) перекрываются друг с другом из-за количества производителей в наборе данных. Есть ли способ динамически изменять размер этих меток/значений по оси x, чтобы они не перекрывались друг с другом при использовании shiny/flexdashboard? То, что я подразумеваю под «динамическим», заключается в том, что размер значений по оси x (т. Е. производителей) изменяется в зависимости от выбора пользователя в раскрывающемся списке. Если есть другие способы решения этой проблемы, кроме динамического изменения значений тиков по оси x, я также открыт для этого.
Вот данные:
structure(list(Toys = c("Slinky", "Slinky", "Slinky", "Slinky",
"Slinky", "Slinky", "Tin Solider", "Tin Solider", "Tin Solider",
"Tin Solider", "Tin Solider", "Tin Solider", "Hungry Hungry Hippo",
"Hungry Hungry Hippo", "Hungry Hungry Hippo", "Hungry Hungry Hippo",
"Hungry Hungry Hippo", "Hungry Hungry Hippo", "Bead Maze", "Bead Maze",
"Bead Maze", "Bead Maze", "Bead Maze", "Bead Maze", "Hula Hoop",
"Hula Hoop", "Hula Hoop", "Hula Hoop", "Hula Hoop", "Hula Hoop",
"Kaleidoscope", "Kaleidoscope", "Kaleidoscope", "Kaleidoscope",
"Kaleidoscope", "Kaleidoscope", "Pogo Stick", "Pogo Stick", "Pogo Stick",
"Pogo Stick", "Pogo Stick", "Pogo Stick", "Jump N' Dunk Trampoline",
"Jump N' Dunk Trampoline", "Jump N' Dunk Trampoline", "Jump N' Dunk Trampoline",
"Jump N' Dunk Trampoline", "Jump N' Dunk Trampoline", "Play-Doh",
"Play-Doh", "Play-Doh", "Play-Doh", "Play-Doh", "Play-Doh", "Mr. Potato Head",
"Mr. Potato Head", "Mr. Potato Head", "Mr. Potato Head", "Mr. Potato Head",
"Mr. Potato Head", "Corn Popper", "Corn Popper", "Corn Popper",
"Corn Popper", "Corn Popper", "Corn Popper", "Let's Go Fishing",
"Let's Go Fishing", "Let's Go Fishing", "Let's Go Fishing", "Let's Go Fishing",
"Let's Go Fishing", "Operation", "Operation", "Operation", "Operation",
"Operation", "Operation", "Ker Plunk", "Ker Plunk", "Ker Plunk",
"Ker Plunk", "Ker Plunk", "Ker Plunk", "Jack-In-The-Box", "Jack-In-The-Box",
"Jack-In-The-Box", "Jack-In-The-Box", "Jack-In-The-Box", "Jack-In-The-Box",
"Xylophone", "Xylophone", "Xylophone", "Xylophone", "Xylophone",
"Xylophone", "Chatter Phone", "Chatter Phone", "Chatter Phone",
"Chatter Phone", "Chatter Phone", "Chatter Phone", "Jumbo Jacks",
"Jumbo Jacks", "Jumbo Jacks", "Jumbo Jacks", "Jumbo Jacks", "Jumbo Jacks",
"Rock 'em Sock 'em Robots", "Rock 'em Sock 'em Robots", "Rock 'em Sock 'em Robots",
"Rock 'em Sock 'em Robots", "Rock 'em Sock 'em Robots", "Rock 'em Sock 'em Robots",
"Silly Putty", "Silly Putty", "Silly Putty", "Silly Putty", "Silly Putty",
"Silly Putty", "TinkerToy", "TinkerToy", "TinkerToy", "TinkerToy",
"TinkerToy", "TinkerToy", "Silly Putty", "Silly Putty", "Silly Putty",
"Silly Putty", "Silly Putty", "Silly Putty", "Red Wagon", "Red Wagon",
"Red Wagon", "Red Wagon", "Red Wagon", "Red Wagon", "Magic 8 Ball",
"Magic 8 Ball", "Magic 8 Ball", "Magic 8 Ball", "Magic 8 Ball",
"Magic 8 Ball"), Manufacturer = c("Manufacturer A", "Manufacturer A",
"Manufacturer A", "Manufacturer A", "Manufacturer A", "Manufacturer A",
"Manufacturer B", "Manufacturer B", "Manufacturer B", "Manufacturer B",
"Manufacturer B", "Manufacturer B", "Manufacturer C", "Manufacturer C",
"Manufacturer C", "Manufacturer C", "Manufacturer C", "Manufacturer C",
"Manufacturer D", "Manufacturer D", "Manufacturer D", "Manufacturer D",
"Manufacturer D", "Manufacturer D", "Manufacturer E", "Manufacturer E",
"Manufacturer E", "Manufacturer E", "Manufacturer E", "Manufacturer E",
"Manufacturer G", "Manufacturer G", "Manufacturer G", "Manufacturer G",
"Manufacturer G", "Manufacturer G", "Manufacturer H", "Manufacturer H",
"Manufacturer H", "Manufacturer H", "Manufacturer H", "Manufacturer H",
"Manufacturer I", "Manufacturer I", "Manufacturer I", "Manufacturer I",
"Manufacturer I", "Manufacturer I", "Manufacturer J", "Manufacturer J",
"Manufacturer J", "Manufacturer J", "Manufacturer J", "Manufacturer J",
"Manufacturer K", "Manufacturer K", "Manufacturer K", "Manufacturer K",
"Manufacturer K", "Manufacturer K", "Manufacturer L", "Manufacturer L",
"Manufacturer L", "Manufacturer L", "Manufacturer L", "Manufacturer L",
"Manufacturer M", "Manufacturer M", "Manufacturer M", "Manufacturer M",
"Manufacturer M", "Manufacturer M", "Manufacturer N", "Manufacturer N",
"Manufacturer N", "Manufacturer N", "Manufacturer N", "Manufacturer N",
"Manufacturer O", "Manufacturer O", "Manufacturer O", "Manufacturer O",
"Manufacturer O", "Manufacturer O", "Manufacturer P", "Manufacturer P",
"Manufacturer P", "Manufacturer P", "Manufacturer P", "Manufacturer P",
"Manufacturer Q", "Manufacturer Q", "Manufacturer Q", "Manufacturer Q",
"Manufacturer Q", "Manufacturer Q", "Manufacturer R", "Manufacturer R",
"Manufacturer R", "Manufacturer R", "Manufacturer R", "Manufacturer R",
"Manufacturer S", "Manufacturer S", "Manufacturer S", "Manufacturer S",
"Manufacturer S", "Manufacturer S", "Manufacturer T", "Manufacturer T",
"Manufacturer T", "Manufacturer T", "Manufacturer T", "Manufacturer T",
"Manufacturer A", "Manufacturer A", "Manufacturer A", "Manufacturer A",
"Manufacturer A", "Manufacturer A", "Manufacturer B", "Manufacturer B",
"Manufacturer B", "Manufacturer B", "Manufacturer B", "Manufacturer B",
"Manufacturer B", "Manufacturer C", "Manufacturer C", "Manufacturer C",
"Manufacturer C", "Manufacturer C", "Manufacturer D", "Manufacturer D",
"Manufacturer D", "Manufacturer D", "Manufacturer D", "Manufacturer D",
"Manufacturer R", "Manufacturer R", "Manufacturer R", "Manufacturer R",
"Manufacturer R", "Manufacturer R"), Price = c(5.99, 6.99, 7.99,
9, 6, 5.54, 7, 9.99, 6.99, 6.75, 8, 7.99, 9.99, 7.99, 5.99, 8.99,
10.99, 9.75, 9.99, 10.15, 8.99, 6.99, 5.99, 9.99, 9.99, 7.75,
8.75, 9.95, 4.5, 5.54, 3.99, 4.5, 7.5, 8.95, 8.9, 6.99, 150.99,
175.99, 170.99, 180.99, 190.99, 175, 310.64, 335.64, 360.64,
385.64, 410.64, 435.64, 7.99, 8.99, 9.05, 9.1, 9.99, 10.15, 6.75,
8.75, 7.75, 9.75, 6.75, 8.75, 10.35, 10.55, 11, 17, 17.75, 18,
6.97, 7.05, 8.97, 9, 8.99, 6.99, 19.99, 21.15, 16.99, 17.99,
18.99, 14.99, 14.96, 14.97, 15.15, 18.17, 19, 50, 6, 7, 8, 7,
9, 10, 10, 11, 12, 11, 12, 9, 5, 6, 7, 7.5, 5, 5, 10.95, 9.95,
9.99, 10.5, 10.95, 9.95, 28, 30, 28, 32, 27, 27.95, 5, 3, 4,
5, 4, 3, 25, 25, 27, 29, 25.5, 28.5, 5.12, 4.95, 5, 4.5, 5.12,
5, 15, 16, 16, 14.99, 15.5, 16, 5, 6.5, 5.5, 7.5, 6, 5), change = c(0,
16.69449082, 14.30615165, 12.640801, -33.33333333, -7.666666667,
0, 42.71428571, -30.03003003, -3.433476395, 18.51851852, -0.125,
0, -20.02002002, -25.03128911, 50.08347245, 22.24694105, -11.28298453,
0, 1.601601602, -11.42857143, -22.24694105, -14.30615165, 66.77796327,
0, -22.42242242, 12.90322581, 13.71428571, -54.77386935, 23.11111111,
0, 12.78195489, 66.66666667, 19.33333333, -0.558659218, -21.46067416,
0, 16.55738791, -2.841070515, 5.848295222, 5.525167136, -8.372166082,
0, 8.047901107, 7.44845668, 6.932120674, 6.482730007, 6.088057666,
0, 12.51564456, 0.667408231, 0.552486188, 9.78021978, 1.601601602,
0, 29.62962963, -11.42857143, 25.80645161, -30.76923077, 29.62962963,
0, 1.93236715, 4.265402844, 54.54545455, 4.411764706, 1.408450704,
0, 1.147776184, 27.23404255, 0.334448161, -0.111111111, -22.24694105,
0, 5.802901451, -19.66903073, 5.885815185, 5.558643691, -21.06371775,
0, 0.06684492, 1.20240481, 19.9339934, 4.56796918, 163.1578947,
0, 16.66666667, 14.28571429, -12.5, 28.57142857, 11.11111111,
0, 10, 9.090909091, -8.333333333, 9.090909091, -25, 0, 20, 16.66666667,
7.142857143, -33.33333333, 0, 0, -9.132420091, 0.40201005, 5.105105105,
4.285714286, -9.132420091, 0, 7.142857143, -6.666666667, 14.28571429,
-15.625, 3.518518519, 0, -40, 33.33333333, 25, -20, -25, 0, 0,
8, 7.407407407, -12.06896552, 11.76470588, -82.03508772, 0, 1.01010101,
-10, 13.77777778, -2.34375, 0, 6.666666667, 0, -6.3125, 3.402268179,
3.225806452, 0, 30, -15.38461538, 36.36363636, -20, -16.66666667
), Dates = c("1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021",
"9/1/2021", "10/1/2021", "1/1/2021", "3/1/2021", "5/1/2021",
"7/1/2021", "9/1/2021", "10/1/2021", "1/1/2021", "3/1/2021",
"5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021", "1/1/2021",
"3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021",
"1/1/2021", "3/1/2021", "5/1/2021", "7/1/2021", "9/1/2021", "10/1/2021"
)), class = "data.frame", row.names = c(NA, -144L))
Вот фактический код:
---
title: "Test"
output: flexdashboard::flex_dashboard
runtime: shiny
---
```{r global, include=FALSE}
library(dplyr)
library(tidyquant)
library(ggplot2)
library(stringr)
library(tidyr)
library(pins)
library(shiny)
library(httr)
library(XML)
library(DT)
library(plotly)
library(purrr)
test_data <- #insert dput here
```
Sidebar {.sidebar}
-----------------------------------------------------------------------
```{r}
selectInput("Toys",
label = "Toys",
choices = c("ALL",unique(sort(test_data$Toys))),
selected = "ALL")
selectInput("Manufacturer",
label = "Manufacturer",
choices = c("ALL", test_data %>%
dplyr::select(Manufacturer) %>%
dplyr::arrange(Manufacturer)),
selected = "ALL")
dateRangeInput(inputId = "Dates",
label = "Date Range",
start = Sys.Date() %m % years(-1),
end = Sys.Date(),
format = 'yyyy-mm')
```
Column
-------------------------------------
```{r}
#Hides initial error messages
tags$style(type="text/css",
".shiny-output-error { visibility: hidden; }",
".shiny-output-error:before { visibility: hidden; }"
)
observe({
# updateSelectInput(inputId = "Toys",
# choices = test_data[test_data$Manufacturer==input$Manufacturer,
# "Toys"])
updateSelectInput(inputId = "Manufacturer",
choices = test_data[test_data$Toys ==input$Toys,
"Manufacturer"] %>%
append('ALL', after = 0))
})
Toys_reactive <- reactive({
test_data[(input$Manufacturer == "ALL" |
test_data$Manufacturer == input$Manufacturer) amp;
(input$Toys == "ALL" |
test_data$Toys == input$Toys),,drop = FALSE]
})
chart_height <- reactive({Toys_reactive() %>%
dplyr::filter(!is.na(Dates)) %>%
dplyr::select(Manufacturer) %>%
unique %>%
nrow * 130})
output$plot <- renderPlotly({
p <- Toys_reactive() %>%
dplyr::filter(!is.na(Dates)) %>%
ggplot(aes(x = Dates, y = Price, text = paste(paste0("Price: $", sprintf("%.2f", Price)),"<br> Date: ", Dates), group = Manufacturer))
geom_point(size = 1.5)
geom_line()
facet_wrap(~Manufacturer, scales = "free", ncol = 1)
theme_bw()
theme(
title = element_text(colour='black'),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
axis.text.x = element_text(size = rel(0.85)),
panel.grid.major = element_line(colour = "grey70", size = 0.1),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.spacing = unit(0.45,"cm")
) #ensuring that plots render properly
ggplotly(p, height = chart_height(), tooltip = "text", xaxis = list(automargin = T)) %>% layout(margin=list(b=25))
})
#Renders the plot above with the proper height
renderUI({
plotlyOutput("plot", height = "100%")
})
```
{.tabset .tabset-fade}
-------------------------------------
### Heat Map
```{r}
renderPlotly({p <- ggplot(Toys_reactive() %>%
dplyr::group_by(Toys, Manufacturer) %>%
dplyr::summarize(change = sum(change, na.rm = TRUE)),
aes(x = Manufacturer, y = Toys))
geom_tile(aes(fill = change))
theme(axis.text.x = element_text(angle = 45, hjust = 1),
axis.title.x = element_blank(),
axis.title.y = element_blank(), legend.key.size = unit(0.5, 'cm'))
scale_fill_viridis_c(option = "B", direction = -1)
ggplotly(p) %>% layout(autosize = T)
})
Вот картина того, что я имею в виду:
Пожалуйста, обратите внимание, что это всего лишь тестовый набор данных, поэтому тепловая карта действительно выглядит пугающе. Это больше для того, чтобы привести наглядный пример.
Ответ №1:
Вы можете сделать это, настроив функцию построения так, чтобы ее форматирование менялось в зависимости от количества категорий, которые она должна отображать. Здесь я настраиваю размер текста оси в соответствии с количеством категорий.
library(tidyverse)
df_var_size <- function(x_cat = 32) {
mtcars %>%
rownames_to_column("car") %>%
slice(1:x_cat) -> mtcars_sized
mtcars_sized %>%
ggplot(aes(car, mpg))
geom_point()
theme(axis.text.x = element_text(
angle = 60, hjust = 1, size = pmin(10, 200 / length(unique(mtcars_sized$car)))))
}
Результаты. Обратите внимание, как при увеличении категорий до 30 текст становится меньше. Я использую pmin
так, чтобы текст не становился больше 10, когда категорий мало.
df_var_size(10)
df_var_size(20)
df_var_size(30)