我想使用 ggplot2 绘制一些不同的数据项,使用两种不同的色标(一种是连续的,一种是来自两个不同 df 的离散的)。我可以按照我想要的方式单独绘制,但我不能让它们一起工作。看来你不能在同一个图中使用两种不同的色标?我见过类似的问题here和here,这让我相信我想要实现的目标在ggplot2中根本不可能实现,但以防万一我错了,我想说明我的问题以查看如果有解决方法。
我有一些 GIS 流数据,其中附加了一些分类属性,我可以绘制这些属性(下面代码中的
p1
)来获取:
我还有一组具有连续响应的位置,我也可以绘制这些位置(下面代码中的
p2
)以获得:
但是我无法将两者结合起来(下面代码中的p3
)。我收到此错误
scales[[prev_aes]] 中的错误:尝试选择少于一个元素
注释掉行
scale_colour_hue("Strahler order") +
将错误更改为
错误:提供给连续刻度的离散值
基本上,ggplot2 似乎对
geom_path
调用和 geom_point
调用使用相同的尺度类型(连续或离散)。因此,当我将离散变量 factor(Strahler)
传递到 scale_colour_gradientn
尺度时,绘图失败。
有办法解决这个问题吗?如果尺度函数有一个
data
参数来告诉它应该从哪里映射或设置属性,那就太神奇了。这可能吗?
非常感谢和下面的可复制代码:
library(ggplot2)
### Download df's ###
oldwd <- getwd(); tmp <- tempdir(); setwd(tmp)
url <- "http://dl.dropbox.com/u/44829974/Data.zip"
f <- paste(tmp,"\\tmp.zip",sep="")
download.file(url,f)
unzip(f)
### Read in data ###
riv_df <- read.table("riv_df.csv", sep=",",h=T)
afr_df <- read.table("afr_df.csv", sep=",",h=T)
vil_df <- read.table("vil_df.csv", sep=",",h=T)
### Min and max for plot area ###
xmin <- -18; xmax <- 3; ymin <- 4; ymax <- 15
### Plot river data ###
p1 <- ggplot(riv_df, aes(long, lat)) +
geom_map( mapping = aes( long , lat , map_id = id ) , fill = "white" , data = afr_df , map = afr_df ) +
geom_path( colour = "grey95" , mapping = aes( long , lat , group = group , size = 1 ) , data = afr_df ) +
geom_path( aes( group = id , alpha = I(Strahler/6) , colour = factor(Strahler) , size = Strahler/6 ) ) +
scale_alpha( guide = "none" ) +
scale_colour_hue("Strahler order") +
scale_x_continuous( limits = c( xmin , xmax ) , expand = c( 0 , 0 ) ) +
scale_y_continuous( limits = c( ymin , ymax ) , expand = c( 0 , 0 ) ) +
coord_map()
print(p1) # This may take a little while depending on computer speed...
### Plot response data ###
p2 <- ggplot( NULL ) +
geom_point( aes( X , Y , colour = Z) , size = 2 , shape = 19 , data = vil_df ) +
scale_colour_gradientn( colours = rev(heat.colors(25)) , guide="colourbar" ) +
coord_equal()
print(p2)
### Plot both together ###
p3 <- ggplot(riv_df, aes(long, lat)) +
geom_map( mapping = aes( long , lat , map_id = id ) , fill = "white" , data = afr_df , map = afr_df ) +
geom_path( colour = "grey95" , mapping = aes( long , lat , group = group , size = 1 ) , data = afr_df ) +
geom_path( aes( group = id , alpha = I(Strahler/6) , colour = factor(Strahler) , size = Strahler/6 ) ) +
scale_colour_hue("Strahler order") +
scale_alpha( guide = "none" ) +
scale_x_continuous( limits = c( xmin , xmax ) , expand = c( 0 , 0 ) ) +
scale_y_continuous( limits = c( ymin , ymax ) , expand = c( 0 , 0 ) ) +
geom_point( aes( X , Y , colour = Z) , size = 2 , shape = 19 , data = vil_df ) +
scale_colour_gradientn( colours = rev(heat.colors(25)) , guide="colourbar" ) +
coord_map()
print(p3)
#Error in scales[[prev_aes]] : attempt to select less than one element
### Clear-up downloaded files ###
unlink(tmp,recursive=T)
setwd(oldwd)
干杯,
西蒙
你可以做到这一点。您需要告诉网格图形将一个图叠加在另一个图上。您必须获得边距和间距等,完全正确,并且您必须考虑顶层的透明度。简而言之...不值得。也可能使情节变得混乱。
但是,我认为有些人可能希望了解如何实现这一目标。注意:我使用了此要点中的代码使顶部图中的元素透明,这样它们就不会使下面的元素变得不透明:
grid.newpage()
pushViewport( viewport( layout = grid.layout( 1 , 1 , widths = unit( 1 , "npc" ) ) ) )
print( p1 + theme(legend.position="none") , vp = viewport( layout.pos.row = 1 , layout.pos.col = 1 ) )
print( p2 + theme(legend.position="none") , vp = viewport( layout.pos.row = 1 , layout.pos.col = 1 ) )
请参阅我的答案
scale_colour_*
两次对于 ggplot2 来说是没有意义的。它会试图将一个强行推向另一个。同一个图表中不能有多个色标,无论其中一个是连续的还是离散的。软件包作者表示他们也无意添加此内容。实现起来相当复杂,并且很容易制作出令人难以置信的混乱图表。 (出于类似的原因,多个 y 轴永远不会被实现。)
ggplot 中的 geom_point (scale_colour_manual) 中的填充和边框颜色
基本上,将 geom_point 与shape = 21, color = NA
结合使用可以让您使用
fill
而不是
color
美学来控制一系列点的颜色。这是我的代码的样子。我知道没有提供任何数据,但希望它能为您提供一个起点:
biloxi +
geom_point(data = filter(train, primary != 'na'),
aes(y = GEO_LATITUDE, x = GEO_LONGITUDE, fill = primary),
shape = 21, color = NA, size = 1) +
scale_fill_manual(values = c('dodgerblue', 'firebrick')) +
geom_point(data = test_map_frame,
aes(y = GEO_LATITUDE, x = GEO_LONGITUDE, color = var_score),
alpha = 1, size = 1) +
scale_color_gradient2(low = 'dodgerblue4', high = 'firebrick4', mid = 'white',
midpoint = mean(test_map_frame$var_score))
注意每次调用 geom_point 如何调用不同的美感(
color
或
fill
)
# OP data is no longer available,
# example by Elio Campitelli from https://eliocamp.github.io/ggnewscale/, modified
library(ggplot2)
library(ggnewscale)
# "melt(volcano)"
topography <- data.frame(expand.grid(x = 1:nrow(volcano), y = 1:ncol(volcano)), z = as.vector(volcano))
# point measurements of something at a few locations
set.seed(42)
measurements <- data.frame(x = runif(30, 1, 80),
y = runif(30, 1, 60),
thing = sample(letters[1:5], 30, replace=TRUE)
)
ggplot(mapping = aes(x, y)) +
geom_contour(data = topography, aes(z = z, color = after_stat(level))) +
# Color scale for topography
scale_color_viridis_c(option = "D") +
# geoms below will use another color scale
new_scale_color() +
geom_point(data = measurements, size = 3, aes(color = thing)) +
# Color scale applied to geoms added after new_scale_color()
scale_color_viridis_d(option = "A")
请记住,同一图中的多个色标