Изменение внешнего вида размера меток фасетов

Я знаю, что вопрос был задан здесь: Есть ли способ увеличить высоту полосы strip.text в фасете?

Я хочу уменьшить высоту полосы strip.text без изменения размера текста. В данном случае всегда остается пространство между текстом и стенками полосы.

Вот что я пробовал до сих пор,

library(gcookbook) # For the data set
library(ggplot2)

ggplot(cabbage_exp, aes(x=Cultivar, y=Weight)) + geom_bar(stat="identity") +
facet_grid(.~ Date) +
theme(strip.text = element_text(face="bold", size=9,lineheight=5.0),
strip.background = element_rect(fill="lightblue", colour="black",
size=1))

В моем случае кажется, что lineheight ни на что не влияет, даже если его изменить на 5. Почему?
Как уменьшить размер полоски, но сохранить размер текста?

введите здесь описание изображения

редактировать после ответа @Sandy Muspratt

мы можем уменьшить размер полосы, если есть только одна строка facets.

g = ggplotGrob(p)
g$heights[c(3)] = unit(.4, "cm")  # Set the height

grid.newpage()
grid.draw(g)

введите здесь описание изображения

Однако в моих реальных данных у меня много строк графика, как показано ниже, и когда я изменил элементы g $ heights, ничего не произошло!

p = ggplot(cabbage_exp, aes(x=Cultivar, y=Weight)) + geom_bar(stat="identity") +
  facet_wrap(~ Date,ncol = 1) +
  theme(strip.text = element_text(face="bold", size=9),
        strip.background = element_rect(fill="lightblue", colour="black",size=1))

введите здесь описание изображения

 g = ggplotGrob(p)
g$heights
#    [1] 5.5pt               0cm                 0.66882800608828cm  #1null               0cm                 0.193302891933029cm
#     [7] 0.66882800608828cm  1null               0cm                 #0.193302891933029cm 0.66882800608828cm  1null              
#    [13] 0.456194824961948cm 0cm                 1grobheight         5.5pt

затем я попытался изменить 1,7 and 11 элементов

g$heights[c(3,7,11)] = unit(.4, "cm")  # Set the height

grid.newpage()
grid.draw(g)

введите здесь описание изображения

Размер метки фасета не изменился.

> g$heights
 [1] 5.5pt                                                       1grobheight                                                
 [3] sum(0.2cm, sum(0.15cm, 0.8128cm, 0cm, 0.15cm), 0.2cm)+0.2cm 0.2                                                        
 [5] 1null                                                       0cm                                                        
 [7] 0.193302891933029cm                                         0.2                                                        
 [9] 1null                                                       0cm                                                        
[11] 0.193302891933029cm                                         0.2                                                        
[13] 1null                                                       0cm                                                        
[15] 0.193302891933029cm                                         0.2                                                        
[17] 1null                                                       0.456194824961948cm                                        
[19] 0cm                                                         1grobheight                                                
[21] 5.5pt  

person Alexander    schedule 22.04.2016    source источник
comment
@hrbrmstr, потому что, когда у меня много окон для facet_wrap, это пустое пространство становится очень важным. если бы я мог контролировать его размер, площадь участка увеличивалась бы для каждого окна. поэтому!   -  person Alexander    schedule 22.04.2016
comment
как было предложено в ответе на ссылку, которую вы разместили в своем вопросе, необходимо немного изменить переменную фасетирования, добавив "\n" в начало и конец каждой строки cabbage_exp$Date <- paste0("\n", cabbage_exp$Date, "\n")   -  person inscaven    schedule 22.04.2016
comment
@inscaven да, я не мог понять. Спасибо!   -  person Alexander    schedule 22.04.2016


Ответы (1)


Использовать поля

Начиная примерно с ggplot2 версии 2.1.0: в theme укажите поля в элементе strip_text (см. здесь ).

library(ggplot2)
library(gcookbook) # For the data set

p = ggplot(cabbage_exp, aes(x=Cultivar, y=Weight)) + geom_bar(stat="identity") +
facet_grid(. ~ Date) +
theme(strip.text = element_text(face="bold", size=9),
strip.background = element_rect(fill="lightblue", colour="black",size=1))

  p +
  theme(strip.text.x = element_text(margin = margin(.1, 0, .1, 0, "cm")))



Оригинальный ответ обновлен до ggplot2 v2.2.0

Ваша диаграмма facet_grid

Это уменьшит высоту полосы (вплоть до нулевой высоты, если хотите). Высота должна быть установлена ​​на одну полосу и три гроба. Это будет работать с вашим конкретным примером facet_grid.

library(ggplot2)
library(grid)
library(gtable)
library(gcookbook) # For the data set

p = ggplot(cabbage_exp, aes(x=Cultivar, y=Weight)) + geom_bar(stat="identity") +
facet_grid(. ~ Date) +
theme(strip.text = element_text(face="bold", size=9),
strip.background = element_rect(fill="lightblue", colour="black",size=1))

g = ggplotGrob(p)

g$heights[6] = unit(0.4, "cm")  # Set the height

for(i in 13:15) g$grobs[[i]]$heights = unit(1, "npc") # Set height of grobs

grid.newpage()
grid.draw(g)

Ваша диаграмма Facet_wrap

На странице есть три полоски. Таким образом, необходимо изменить три высоты полосы и три высоты вставки.

Следующее будет работать с вашим конкретным примером facet_wrap.

p = ggplot(cabbage_exp, aes(x=Cultivar, y=Weight)) + geom_bar(stat="identity") +
  facet_wrap(~ Date,ncol = 1) +
  theme(strip.text = element_text(face="bold", size=9),
        strip.background = element_rect(fill="lightblue", colour="black",size=1))

g = ggplotGrob(p)

for(i in c(6,11,16)) g$heights[[i]] = unit(0.4,"cm")   # Three strip heights changed
for(i in c(17,18,19)) g$grobs[[i]]$heights <-  unit(1, "npc")   # The height of three grobs changed

grid.newpage()
grid.draw(g)

Как найти соответствующие высоты и гробы?

g$heights возвращает вектор высот. Высота 1null — это панели графика. Высоты полосы на единицу выше, то есть 6, 11, 16.

g$layout возвращает фрейм данных с именами grobs в последнем столбце. Гробы, которым нужно изменить свою высоту, - это те, имена которых начинаются с «полосы». Они находятся в рядах 17, 18, 19.

Немного обобщить

p = ggplot(cabbage_exp, aes(x=Cultivar, y=Weight)) + geom_bar(stat="identity") +
  facet_wrap(~ Date,ncol = 1) +
  theme(strip.text = element_text(face="bold", size=9),
        strip.background = element_rect(fill="lightblue", colour="black",size=1))

g = ggplotGrob(p)

# The heights that need changing are in positions one less than the plot panels
pos =  c(subset(g$layout, grepl("panel", g$layout$name), select = t))
for(i in pos) g$heights[i-1] = unit(0.4,"cm")

# The grobs that need their heights changed:
grobs = which(grepl("strip", g$layout$name))
for(i in grobs) g$grobs[[i]]$heights <-  unit(1, "npc")      
grid.newpage()
grid.draw(g)

Несколько панелей в ряду

Можно использовать почти такой же код, даже с заголовком и легендой, расположенными сверху. Произошло изменение в вычислении pos, но даже без этого изменения код работает.

library(ggplot2)
library(grid)

# Some data
df = data.frame(x= rnorm(100), y = rnorm(100), z = sample(1:12, 100, T), col = sample(c("a","b"), 100, T))

# The plot
p = ggplot(df, aes(x = x, y = y, colour = col)) +
   geom_point() +
   labs(title = "Made-up data") + 
   facet_wrap(~ z, nrow = 4) +
   theme(legend.position = "top")

g = ggplotGrob(p)

# The heights that need changing are in positions one less than the plot panels
pos =  c(unique(subset(g$layout, grepl("panel", g$layout$name), select = t)))
for(i in pos) g$heights[i-1] = unit(0.2, "cm")

# The grobs that need their heights changed:
grobs = which(grepl("strip", g$layout$name))
for(i in grobs) g$grobs[[i]]$heights <-  unit(1, "npc") 

grid.newpage()
grid.draw(g)
person Sandy Muspratt    schedule 19.05.2016
comment
дорогая Сэнди, я ценю твой ответ. Я проверил ваше решение, и оно работает, только если у меня есть один ряд графиков. Но в случае 3 строки графика это не работает. Я пытался изменить каждые некоторые параметры, но это не помогло. Может быть, я что-то упустил, пожалуйста, смотрите измененный вопрос. - person Alexander; 20.05.2016
comment
@ Александр, исходное решение относится к примеру facet_grid. facet-wrap требует другого подхода. См. правку с заголовком facet_wrap. - person Sandy Muspratt; 20.05.2016
comment
Спасибо за ваш элегантный ответ. Это невероятно с воспроизводимыми данными здесь. С другой стороны, когда я наконец применяю grid.draw(g) к своим реальным данным, я получаю Error in grid.Call.graphics(L_setviewport, vp, TRUE) : INTEGER() can only be applied to a 'integer', not a 'NULL' - person Alexander; 20.05.2016
comment
Вы получаете эту ошибку с примером, размещенным здесь, или с вашими реальными данными? - person Sandy Muspratt; 20.05.2016
comment
с моими реальными данными. Я могу построить свои реальные данные без проблем. Я добавил, как это выглядит временно, в конец вопроса. - person Alexander; 20.05.2016
comment
Хорошо, возможно, проблема связана с несколькими панелями подряд. В предыдущем примере была только одна панель на строку. Я посмотрю на это, но, может быть, завтра. Но все же, вы можете опубликовать свою команду. - person Sandy Muspratt; 20.05.2016
comment
Я добавил код в ответ. Но я не могу воспроизвести вашу ошибку. Во-первых, используете ли вы последние версии для R и ggplot2? Затем начните с самого простого сюжета. Кроме того, какие значения вы получаете для pos и grobs? Согласны ли они с тем, что вы получите от g$heights и g$layout? - person Sandy Muspratt; 21.05.2016
comment
работал ровно. Спасибо большое. очень ценил это. Хороших выходных. - person Alexander; 21.05.2016
comment
сегодня я снова попробовал ваш Multiple panels per-row пост. Но у меня ошибка Error in grid.Call.graphics(L_setviewport, vp, TRUE) : INTEGER() can only be applied to a 'integer', not a 'NULL'. Я думаю, что ошибка возникает, когда guides потому что, когда я добавил этот код guides(col="none"), ошибки нет. Но на самом деле мне тоже нужны эти гиды! Как я могу это решить? - person Alexander; 23.05.2016
comment
Я не. Независимо от положения легенды, есть ли легенда или нет, я улавливаю сюжет. Используете ли вы код и фрейм данных точно так, как указано в ответе? Вы получаете ggplot? Получив ggplot grob, можете ли вы нарисовать рост с помощью grid.draw? Что вы получаете от pos? После того, как вы примените первый набор изменений высоты, что вы получите для g$heights? что вы получаете за grobs? Что вы получите за g$grobs[[13]]$heights после применения второго набора изменений? - person Sandy Muspratt; 23.05.2016
comment
Ok. Я получил за pos =$t [1] 5 9 13 17 за grobs [1] 14 15 16 17 18 19 20 21 22 23 24 25 и g$grobs[[13]]$heights отдав NULL - person Alexander; 23.05.2016
comment
Хорошо, вместо 14 должно быть g$grobs[[14]]$heights, или 15, или 16 и т. д. Кроме того, что вы получаете за g$heights? - person Sandy Muspratt; 23.05.2016
comment
да я вижу. Ты прав. Я получил за g$grobs[[14]] 1npc. а для g$heighs я помещаю результат в конец вопроса. Пожалуйста, найдите его. - person Alexander; 23.05.2016
comment
Вы заметите, что высоты 4, 8, 12 и 16 равны 0.2. Они должны быть 0.2cm. Это говорит мне о том, что ваша версия сетки устарела. Какую версию R вы используете? Если не 3.3.0, то обновите R, который, в свою очередь, обновит сетку. - person Sandy Muspratt; 23.05.2016
comment
И действительно, когда я использую старую версию R (и, следовательно, сетку), я получаю сообщение об ошибке. Обновите и все будет хорошо. - person Sandy Muspratt; 23.05.2016
comment
Да, вы были правы насчет версии R. Я установил новейшую версию R, и проблема была решена. Спасибо чувак! - person Alexander; 23.05.2016
comment
Отличный ответ, это также помогает plotly::ggplotly при обертывании ggplot2 многофакторным facet_wrap (~a + b), поскольку полосы сглажены в plotly. Спасибо. - person Yang Liu; 08.11.2019