2015-10-27 3 views
3

Можно ли вручную указать количество факторов, показанных на столбе в легенде ggplot? Это воспроизводимый пример демонстрирует то, что я пытаюсь сделать:Указание количества факторов в столбцах легенды

#loading libraries 
library(ggplot2) 

#Creating hypothetical dataframe 
services<-data.frame(study=c(0),category=c(0),subcategory=c(0)) 
services<-services[-1,] 
services[1:15,1]<-c(1:15) 

services[1:4,2]<-c("Provisioning", "Regulating", "Suporting", "Cultural") 
services[5:8,2]<-c("Provisioning", "Regulating", "Suporting", "Cultural") 
services[9:10,2]<-c("Provisioning", "Regulating") 
services[11:15,2]<-c("Provisioning", "Regulating", "Suporting", "Cultural", "Provisioning") 

services[1:4,3]<-c("Water supply", "Climate regulation", "Soil formation",  "Recreation") 
services[5:8,3]<-c("Fisheries", "Water purification", "Habitat", "Recreation") 
services[9:10,3]<-c("Water supply", "Flood regulation") 
services[11:15,3]<-c("Agriculture", "Water purification", "Soil formation", "Aesthetics", "Fisheries") 

services 

#Manually re-ordering subcategory factors by larger categories and by number of occurences in the df (I am also looking for a better way to do this, as it must exist!!) 
table(services$subcategory) 
services$subcategory <- factor(services$subcategory, 
          levels=c(#Cultural services 
           "Recreation", "Aesthetics", 
           #Provisioning services 
           "Fisheries", "Water supply", "Agriculture", 
           #Regulating services 
           "Water purification", "Climate regulation","Flood regulation", 
           #Supporting services 
           "Soil formation", "Habitat")) 


#Creating figure 
ggplot(services, aes(category, fill=subcategory)) + geom_bar() + 
theme(legend.position="right") + 
guides(fill=guide_legend(ncol=4, title="Ecosystem Service Sub Categories"))+ 
xlab("Ecosystem Service Type") + 
ylab("Number of times each ecosystem service was evaluated") 

The Figure produced by this code

What would like the figure legend to look like instead!

An Even more advanced way I'd love the figure to come out as

Хотя this предложение и this один получить в этой идее, они делают не создавайте результат, который я ищу. Я размышлял над этой проблемой в течение нескольких недель и часами осматривал решение, потому что я против того, чтобы вручную выполнять эти настройки в точке питания, иллюстраторе и т. Д. Не могу найти хороший ответ, теперь я обращаюсь к вы, ребята! Спасибо за любую помощь!

+0

Прочитано [документацию] (http://docs.ggplot2.org/current/guide_legend.html) для 'guide_legend()'? –

+0

Да! Я определенно просмотрел это. Поскольку guide_legend() позволяет настроить многие аспекты легенды, такие как количество строк и столбцов, похоже, что здесь вы можете настроить количество факторов, которые появляются в каждой строке или столбце. Если я ошибаюсь, объясните! Я был бы счастлив разобраться в этом! –

+0

Достаточно справедливо, тогда вы сможете поддразнивать ответ на свою проблемную форму [этот ответ SO] (http://stackoverflow.com/a/27804153/1305688) –

ответ

1

Ha! В то время как Хэдли подтвердил, что это невозможно из-за ggplot2 (см. Ссылку в комментарии), существует очень простой способ сделать это, ограниченное максимальным количеством эстетики, которые связаны с легендами в ggplot2.

Что я сделал, создано четыре фиктивных кадра данных и построено четыре различных объекта эстетики (размер, цвет, альфа, тип линии) за пределами окна печати. Затем вы можете переопределить эстетику легенды, чтобы они выглядели как цвета заливки. Отключите оригинальную легенду заполнения и вуаля!

Я знаю упорядочивания групп и внутри группы не совсем то, что вы хотели, но это должно быть достаточно легко изменить с уровнями факторов и т.д.

Оригинальный сюжет

http://i.stack.imgur.com/LXmeo.png

Новая земля

http://i.imgur.com/1HyNdlV.png

Код

##################### 
# Original code 
##################### 

#loading libraries 
library(ggplot2) 

#Creating hypothetical dataframe 
services<-data.frame(study=c(0),category=c(0),subcategory=c(0)) 
services<-services[-1,] 
services[1:15,1]<-c(1:15) 

services[1:4,2]<-c("Provisioning", "Regulating", "Suporting", "Cultural") 
services[5:8,2]<-c("Provisioning", "Regulating", "Suporting", "Cultural") 
services[9:10,2]<-c("Provisioning", "Regulating") 
services[11:15,2]<-c("Provisioning", "Regulating", "Suporting", "Cultural", "Provisioning") 

services[1:4,3]<-c("Water supply", "Climate regulation", "Soil formation",  "Recreation") 
services[5:8,3]<-c("Fisheries", "Water purification", "Habitat", "Recreation") 
services[9:10,3]<-c("Water supply", "Flood regulation") 
services[11:15,3]<-c("Agriculture", "Water purification", "Soil formation", "Aesthetics", "Fisheries") 
services$subcategory <- factor(services$subcategory, levels=c("Recreation", "Aesthetics","Fisheries", "Water supply", "Agriculture","Water purification", "Climate regulation","Flood regulation","Soil formation", "Habitat")) 

##################### 
# New code 
##################### 

# Create dummy variables 
cultural <- data.frame(Cultural_Services = c("Recreation","Aesthetics"),category = c("Cultural","Cultural")) 
provisional <- data.frame(Provisioning_Services = c("Fisheries","Water Supply","Agricultre"), category = c("Provisioning","Provisioning","Provisioning")) 
regulating <- data.frame(Regulating_Services = c("Water Purification","Climate Regulation","Flood Regulation"), category = c("Regulating","Regulating","Regulating")) 
supporting <- data.frame(Supporting_Services = c("Soil Formation","Soil Formation", "Habitat", "Habitat"), x = c("Regulating","Suporting","Regulating","Suporting"),y=c(-1,-1,-2,-2)) 

## Create plot 
ggplot() + 
## Plot the four dummy layer outside of the intended plotting area 
    geom_point(data = provisional, aes(x = category, y = -1, size = Provisioning_Services)) + 
    geom_point(data = cultural, aes(x = category, y = -1, color = Cultural_Services)) + 
    geom_point(data = regulating, aes(x = category, y = -1, alpha = Regulating_Services)) + 
    geom_line(data = supporting, aes(x = x, y = y, linetype = Supporting_Services)) + 
## Add in your real plot goal 
    geom_bar(data = services, aes(category, fill=subcategory)) + 
## Remove the Fill legend 
    scale_fill_hue(guide="none") + 
## Override the guide aesthetics to make them look like fill colors 
    guides(size = guide_legend(override.aes = list(colour = c("#A3A500","#39B600","#00BF7D"),fill = c(NA,NA,NA), shape = c(15,15,15), size = c(8,8,8)),title="Provisioning Services"), 
     color = guide_legend(override.aes = list(colour = c("#F8766D","#D89000"), shape = c(15,15), size = c(8,8)),title = "Cultural Services"), 
     alpha = guide_legend(override.aes = list(colour = c("#00BFC4","#00B0F6","#9590FF"), shape = c(15,15,15),size = c(8,8,8)), title = "Regulating Services"), 
     linetype = guide_legend(override.aes = list(colour = c("#E76BF3","#FF62BC"), shape = c(15,15), size = c(8,8)),title = "Supporting Services")) + 
## Adjust the plot range to hide all the extra layers 
    ylim(0,5) + 
    xlab("Ecosystem Service Type") + 
    ylab("Number of times each ecosystem service was evaluated") 
#> Warning: Removed 3 rows containing missing values (geom_point). 
#> Warning: Removed 2 rows containing missing values (geom_point). 
#> Warning: Removed 3 rows containing missing values (geom_point). 
#> geom_path: Each group consist of only one observation. Do you need to adjust the group aesthetic? 
+0

Твиты Хэдли: https://twitter.com/ hadleywickham/status/660101332058042370 и https://twitter.com/hadleywickham/status/660103377792045056 –

+0

Для получения дополнительной информации/примеров override.aes ​​() проверьте это сообщение: http://zevross.com/blog/2014/08/ 04/beautiful-plotting-in-ra-ggplot2-cheatsheet-3/# manual-add-legend-items-guide-override.aes ​​ –

+0

Да, также просто понял, что 'show_col (hue_pal())' дал мне неправильный гекс коды для синих цветов Regulatory Services.Сброс всех цветов вручную (что вы должны делать в любом случае, так как оттенок является сложной палитрой для дифференциации) устранит проблему. –

0

У меня была аналогичная проблема, сегодня утром, и ударил по этому частичному решению.

ggplot(data = services, 
     mapping = aes(x = category, fill = interaction(category, subcategory, sep = ', '))) + 
    geom_bar() + 
    guides(fill = guide_legend(title = 'Category and subcategory')) 
Смежные вопросы