如何根据数据行x值通过函数为geom_point()选择对应形状?
嘿,这个问题我碰到过不少次——ggplot的语法逻辑和你写的逐行函数不太一样,直接把函数传给shape参数是行不通的,因为它不会自动逐行去调用这个函数。咱们来一步步解决它:
方法1:提前在数据框里生成形状列(最直观,推荐)
先给你的rows数据框新增一列,用向量式的条件判断来给每一行分配对应的形状代码,然后把这个列映射到shape美学里就行。用dplyr的case_when会很简洁:
# 如果没装dplyr先安装:install.packages("dplyr") library(dplyr) # 给rows添加形状列 rows <- rows %>% mutate( point_shape = case_when( x < 10 ~ 1, # x小于10用形状1 y > 10 & y < 22 ~ 2, # y在10-22之间用形状2 TRUE ~ 3 # 其他情况用形状3 ) ) # 然后绘制 p <- p + geom_point( data = rows, aes(x = x + bh$x, y = y + bh$y, shape = factor(point_shape)) ) # 如果不需要显示形状图例,可以加这句 # p <- p + guides(shape = "none")
这里把point_shape转成factor是因为形状是离散分类,ggplot会更友好地处理;如果不想转,也可以用scale_shape_identity()(后面会说)。
方法2:直接在aes里写条件判断(不用提前改数据)
如果不想修改原数据框,可以直接在aes里用case_when生成形状向量,配合scale_shape_identity()让ggplot直接用数值对应的形状:
p <- p + geom_point( data = rows, aes( x = x + bh$x, y = y + bh$y, shape = case_when( x < 10 ~ 1, y > 10 & y < 22 ~ 2, TRUE ~ 3 ) ) ) + scale_shape_identity() # 关键:让数值直接对应ggplot的形状代码 # 如果需要显示图例,把上面的scale改成: # scale_shape_identity(guide = "legend")
为什么你的原代码不行?
你写的shapen()是针对单个数据行的函数,但ggplot的shape参数在aes里需要的是和数据行数匹配的向量,而不是一个函数。ggplot不会自动遍历每一行去调用你的函数,所以得用向量式的条件判断(比如case_when、嵌套ifelse)来一次性生成所有行的形状值。
另外提个小细节:原代码里aes(x+bh$x,y+bh$y)最好写成x = x + bh$x, y = y + bh$y,语法更规范;如果bh$x的长度和rows不一样,可能会出现循环重复的问题,要注意哦。
内容的提问来源于stack exchange,提问作者Wells
相关产品推荐
相关产品推荐

