Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 用圆点绘制植被样带_R_Ggplot2 - Fatal编程技术网

R 用圆点绘制植被样带

R 用圆点绘制植被样带,r,ggplot2,R,Ggplot2,我有一个数据集,其中有(很多)样带,包括土地高度(x是水平距离,z是海拔,单位都是米)和植被结构。b_-ml、b_-kl1、b_-kl2和b_-s1是苔藓层、草本层1、草本层2和灌木层的覆盖率,单位为%和h_??是相同层的高度(苔藓层始终为3厘米)。我想用有吸引力的图表展示这些数据。以下是数据样本(1个横断面): 我曾尝试使用geom_线和geom_点范围绘制它们,使用密度作为alpha,但这看起来不太好: #set the terrein heigth ld <- 2 p <- g

我有一个数据集,其中有(很多)样带,包括土地高度(x是水平距离,z是海拔,单位都是米)和植被结构。b_-ml、b_-kl1、b_-kl2和b_-s1是苔藓层、草本层1、草本层2和灌木层的覆盖率,单位为%和h_??是相同层的高度(苔藓层始终为3厘米)。我想用有吸引力的图表展示这些数据。以下是数据样本(1个横断面):

我曾尝试使用geom_线和geom_点范围绘制它们,使用密度作为alpha,但这看起来不太好:

#set the terrein heigth
ld <- 2
p <- ggplot(df, aes(x=X,y=Z)) + geom_line()

#add the vegetation layers
p + geom_line(aes(x=X,y=Z+0.02, alpha = b_ml), size = ld, color = "darkgreen") + 
    geom_line(aes(x=X,y=Z+h_kl1/100, alpha = b_kl1), size = ld, color = "green") +  #divide by 100 because z is in meters and h in cm
    geom_line(aes(x=X,y=Z+h_kl2/100, alpha = b_kl2), size = ld, color = "green") +
    geom_line(aes(x=X,y=Z+h_s1/100, alpha = b_s1), size = ld, color = "brown") +
  theme_bw()

我想我想做一个更好看的图,用点的密度表示图层的密度。就像《自然》中的这张照片:

基本上,两层之间的区域由点填充,点的数量取决于密度/覆盖率。
但我有点被困在如何到达那里。我也考虑过“geom_point”和“geom_dotplot”,但这包括手工计算点


对如何实现这一目标有何建议?例如,使用哪种几何模型(抖动?),或者如何重构我的数据?

我认为你没有实际的数据来创建一个图作为你的例子,仅仅因为他们似乎有一个实际吨的数据点(个人观察?某种扫描技术?),而你只有密度估计。从中得出的结论充其量也会让人感到困惑,而且可能会产生误导。如果你有计算这些密度的原始数据,那么这可能是一个不同的故事。下面是一些可以绘制的绘图示例:

首先,我以整洁的格式重新排列数据,使事情变得更有意义:

library(dplyr)
library(tidyr)

densities <- df %>% 
  select(-h_kl1, -h_kl2, -h_s1) %>% 
  gather('type', 'density', b_ml, b_kl1, b_kl2, b_s1) %>% 
  mutate(type = substring(type, 3))
heights <- df %>% 
  select(-b_ml, -b_kl1, -b_kl2, -b_s1) %>% 
  gather('type', 'height', h_kl1, h_kl2, h_s1) %>% 
  mutate(type = substring(type, 3))
df2 <- left_join(densities, heights) %>% 
  mutate(height = ifelse(type == 'ml', 0.03, height / 100),
         type = factor(type, levels = c('s1', 'kl2', 'kl1', 'ml')))

一个问题是,
ml
几乎是不可见的,因为它的尺度与其他的不同。我们可以试着避开:

ggplot(df2, aes(X, Z)) +
  geom_line() +
  geom_linerange(aes(ymin = Z, ymax = Z + height, alpha = density, col = type), 
                 size = 2, position = position_dodge(1))

那帮不了什么忙。也许是刻面:

ggplot(df2, aes(X, Z)) +
  geom_line() +
  geom_linerange(aes(ymin = Z, ymax = Z + height, alpha = density, col = type), size = 4) +
  facet_wrap(~type)

最后一个选择:

ggplot(df2, aes(X, Z)) +
  geom_line() +
  geom_point(aes(y = Z + height, size = density, col = type), alpha = 0.6)

我认为这张照片非常清楚地显示了植被的发展趋势。我喜欢这样,即对不同类别给予同等重视

包括部分:

ggplot(df2, aes(X, Z)) +
  geom_line() +
  geom_segment(aes(xend = X, yend = Z + height), alpha = 0.1) +
  geom_point(aes(y = Z + height, size = density, col = type), alpha = 0.8)

我自己已经非常接近使用geom_抖动的解决方案。为了说明我想做什么(并反驳“捏造数据”和“向观察者头脑中灌输错误想法”的毫无根据的指控[sic]),我将在这里发布我的尝试:

#make a tidy data.frame (taken from @Axeman)
library(dplyr)
library(tidyr)

densities <- df %>% 
  select(-h_kl1, -h_kl2, -h_s1) %>% 
  gather('type', 'density', b_ml, b_kl1, b_kl2, b_s1) %>% 
  mutate(type = substring(type, 3))
heights <- df %>% 
  select(-b_ml, -b_kl1, -b_kl2, -b_s1) %>% 
  gather('type', 'height', h_kl1, h_kl2, h_s1) %>% 
  mutate(type = substring(type, 3))
df2 <- left_join(densities, heights) %>% 
  mutate(height = ifelse(type == 'ml', 0.03, height / 100),
         type = factor(type, levels = c('s1', 'kl2', 'kl1', 'ml')))

# repeat rows according to density
# multiply density by 100: 1% will be 10 dots, 100%, 1000 dots and NA -> 1 (jitter can't handle NA)
df2$repli <- df2$density*1000
df2$repli[is.na(df2$repli)] <- 1

df3 <- df2[rep(rownames(df2), df2$repli), ]

require(ggplot2)

p <- ggplot(df3, aes(x=X,y=Z)) + geom_line(size = 1.5, colour = "gray") + theme_bw()

p + #geom_line(aes(y = Z + height, col = type)) +
  geom_jitter(aes(y = Z + height/2, col = type), position = position_jitter(width = 1, height = df3$height), 
                size = 0.0001, alpha = 0.1 ) +
  scale_color_manual(values = c("brown", "#CCFF00", "#33CC00","#666600"))
#制作一个整洁的data.frame(取自@Axeman)
图书馆(dplyr)
图书馆(tidyr)
密度%
选择(-h_kl1,-h_kl2,-h_s1)%>%
聚集('类型','密度',b_ml,b_kl1,b_kl2,b_s1)%>%
突变(类型=子字符串(类型,3))
高度%
选择(-b_ml,-b_kl1,-b_kl2,-b_s1)%>%
聚集('类型','高度',高铀kl1,高铀kl2,高铀s1)%>%
突变(类型=子字符串(类型,3))
df2%
变异(高度=ifelse(类型='ml',0.03,高度/100),
类型=系数(类型,级别=c('s1','kl2','kl1','ml'))
#根据密度重复行
#密度乘以100:1%将是10点,100%,1000点和NA->1(抖动无法处理NA)

我假设你的问题不是“我想让它看起来漂亮”,而是“我怎样才能达到那个自然的情节”。在这种情况下,我的猜测是
geom_point
(但它还需要更多的数据点才能看起来像自然点)。这能让你更接近你想要的吗?@RHA我有点困惑。如果我想在绘图中有一个点,我需要知道它的坐标。这意味着,我需要有数据。所以我需要的数据点和图中的点一样多。如果此数据不存在(因为每个高度只有一个数据点),则必须创建它,然后使用
jitter
例如(将其位置随机化)和
geom_点
。你必须使用密度来确定你需要的“人工数据”的数量。这会在你原来的圆点周围形成一团圆点(当然你可以在空间中移动它…)。但是看看那幅自然图,我不认为这些圆点仅仅意味着密度——它们也会形成图案,不是吗?这可能很难向非植被生态学家解释。在野外,不可能测量每株植物或每根树枝的高度。因此,估计每层的密度和平均最大高度。用随机点表示这一点并不令人困惑,但实际上非常接近现实。自然图确实可能是用某种扫描技术绘制的,我的数据不同。我只是把它作为我所追求的一个例子。如果你能承认这对非植被生态学家来说是令人困惑的,想象一下神经科学家是多么困惑:)我想我终于得到了你所需要的,但我和@Axeman在这方面的数据模拟是同舟共济的。如果自然情节是一个特定的技术的结果,我会认为这是一个额外的理由反对——从那时起,你将一个错误的想法投入到观察者的头脑中(即,这些点对应于实际的数据点,而这些点不属于实际的数据点)。我知道这不是我的领域。在编写代码之前请仔细考虑(这样它们就不会浪费)。谢谢你的努力,但这不是我想要的。这些面对我没有吸引力,因为这些层一起形成了一个结构,并且总的绘图数量是原来的4倍。堆叠它们可能是更好的选择,但仍然不理想。我认为带抖动的geom_点是一种方法,根据密度复制点。午饭后我再试试。堆积会歪曲他们的身高。我尊重地不同意变戏法数据是件好事。是的,必须先减去前面的图层。@RHA增加了一个附加选项。我没有考虑到这一点,一点也不坏(+1)。我会继续寻找其他选择,但这是迄今为止最好的选择。
ggplot(df2, aes(X, Z)) +
  geom_line() +
  geom_point(aes(y = Z + height, size = density, col = type), alpha = 0.6)
ggplot(df2, aes(X, Z)) +
  geom_line() +
  geom_segment(aes(xend = X, yend = Z + height), alpha = 0.1) +
  geom_point(aes(y = Z + height, size = density, col = type), alpha = 0.8)
#make a tidy data.frame (taken from @Axeman)
library(dplyr)
library(tidyr)

densities <- df %>% 
  select(-h_kl1, -h_kl2, -h_s1) %>% 
  gather('type', 'density', b_ml, b_kl1, b_kl2, b_s1) %>% 
  mutate(type = substring(type, 3))
heights <- df %>% 
  select(-b_ml, -b_kl1, -b_kl2, -b_s1) %>% 
  gather('type', 'height', h_kl1, h_kl2, h_s1) %>% 
  mutate(type = substring(type, 3))
df2 <- left_join(densities, heights) %>% 
  mutate(height = ifelse(type == 'ml', 0.03, height / 100),
         type = factor(type, levels = c('s1', 'kl2', 'kl1', 'ml')))

# repeat rows according to density
# multiply density by 100: 1% will be 10 dots, 100%, 1000 dots and NA -> 1 (jitter can't handle NA)
df2$repli <- df2$density*1000
df2$repli[is.na(df2$repli)] <- 1

df3 <- df2[rep(rownames(df2), df2$repli), ]

require(ggplot2)

p <- ggplot(df3, aes(x=X,y=Z)) + geom_line(size = 1.5, colour = "gray") + theme_bw()

p + #geom_line(aes(y = Z + height, col = type)) +
  geom_jitter(aes(y = Z + height/2, col = type), position = position_jitter(width = 1, height = df3$height), 
                size = 0.0001, alpha = 0.1 ) +
  scale_color_manual(values = c("brown", "#CCFF00", "#33CC00","#666600"))