在循环内的ggplot中生成一致的动态调色板? [英] Generating a consistent dynamic color palette in ggplot within a loop?
问题描述
我有一个名为d1的数据集,类似于:
location,depth.from,depth.to,val,type
我有一个循环为每个独特的位置创建一个相当复杂的图(它将许多事情粘合在一起> grid.arrange
,这就是为什么我无法在位置上使用 facet_wrap
来保持图例/颜色一致情节的一部分)。
假设类型有4个类别,当一个地点的类型数量不同于另一个地点时,问题是每个地点的颜色不一致情节。我可以手动强制他们是相同的,但我试图推广这个功能。 Google让我失望了。
对于下面的块,d1是基于位置类型的数据的子集,例如,
d1 < - 子集(myData,location == location.list [i])
$ c
$ b 查看循环内的图:
p1 < - ggplot(data = d1,aes(y = val,x = depth.from))+
图层(geom =point,size = 2)+
geom_rect(data = d1,aes(xmin = Depth.to,xmax = Depth.from,ymin = 0,ymax = 100,fill = type),linetype = 0,alpha = 0.3)+
scale_fill_brewer =Set1)
geom_rect命令正在处理数据并基于深度和深度到,根据填充类型创建叠加层。我可以使用 scale_fill_manual(Lith,c(Val1=DodgerBlue4...)
等来手动设置它,但是这会破坏目的。 :类型喜欢我想要的东西:
Bird_one =蓝色
Bird_two =红色
Bird_three =绿色
我希望 bird_three
为绿色,甚至如果 bird_two
不存在,而不必使用 scale_fill_manual
显式设置。是否有设置全局
myData< - read.csv( mydata.csv
typeList< - unique(myData $ type)
解决方案 很晚,但实际上通过设置 scale_fill_discrete(drop = F)
plots< - lapply(dfs,function(df){
ggplot(df,
aes(
x = location,fill = typ e,
y =(depth.from + depth.to)/ 2,
ymin = depth.from,ymax = depth.to
))+
geom_crossbar()+ scale_fill_discrete (drop = F)
})
library(gridExtra)
do.call(grid.arrange,plot)
以下是我使用的虚拟数据:
set.seed(12)
items < - 2
dfs< -
replicate(2,简化= F,
data.frame(
位置=样本(字母,项目),
深度.from = runif(items,-10,-5),
depth.to = runif(items,5,10),
val = runif(items),
type = factor
sample(c(Bird_one,Bird_two,Bird_three),items),
levels = c(Bird_one,Bird_two,Bird_three)
)) )
I have a data set called d1 similar to:
location, depth.from, depth.to, val, type
I have a loop that creates a fairly complex plot for each unique location (it's glueing together many things using grid.arrange
, which is why I can't use facet_wrap
on the location to keep the legend/color consistent of one part of the plot).
Say there are 4 categories for "type", the problem when one location has a different number of "types" than the other, the colors assigned are not consistent between each plot. I can manually force them to be the same, but I am trying to generalize this function. Google has failed me.
For the following block, d1 is a subset of the data based on the location type, e.g.
d1 <- subset(myData, location == location.list[i])
Looking at the plot, which is within the loop:
p1 <- ggplot(data = d1, aes (y=val, x=depth.from))+
layer(geom = "point", size = 2) +
geom_rect(data=d1, aes(xmin=Depth.to, xmax=Depth.from, ymin=0, ymax=100, fill = type), linetype =0, alpha=0.3)+
scale_fill_brewer(palette="Set1")
the geom_rect command is going through the data and based on the depth from and depth to, creating a overlay based on fill type. I can use scale_fill_manual("Lith", c("Val1" = "DodgerBlue4"...)
etc to manually set it, but that defeats the purposes. If I have:types like where I want something like:
Bird_one = blue
Bird_two = red
Bird_three = green
I want bird_three
to be green, even if bird_two
doesn't exist, without having to explicitly set it using scale_fill_manual
. Is there a way to set a global list of names for the color palette? Perhaps by providing the array from something like:
myData <- read.csv("mydata.csv"
typeList <- unique(myData$type)
解决方案 Pretty late, but there actually is a trivial solution by setting scale_fill_discrete(drop=F)
plots <- lapply(dfs, function(df) {
ggplot(df,
aes(
x=location, fill=type,
y=(depth.from + depth.to) / 2,
ymin=depth.from, ymax=depth.to
) ) +
geom_crossbar() + scale_fill_discrete(drop=F)
})
library(gridExtra)
do.call(grid.arrange, plots)
And here is dummy data I used:
set.seed(12)
items <- 2
dfs <-
replicate(2, simplify=F,
data.frame(
location=sample(letters, items),
depth.from=runif(items, -10, -5),
depth.to=runif(items, 5, 10),
val=runif(items),
type=factor(
sample(c("Bird_one", "Bird_two", "Bird_three"), items),
levels=c("Bird_one", "Bird_two", "Bird_three")
) ) )
这篇关于在循环内的ggplot中生成一致的动态调色板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文