堆积条的顺序ggplot2 - 土壤剖面

时间:2017-10-20 22:10:19

标签: r ggplot2

ggplot2中条形图的documentation表示(参见示例3):

  

当多个条形放置在同一位置时,条形图会自动堆叠。填充顺序旨在与图例匹配。

由于某种原因,第二句对我不起作用。这是一个示例数据集,它代表上面的土壤层(落叶等)和地下(实际土壤):

df <- structure(list(horizon = structure(c(5L, 3L, 4L, 2L, 1L, 5L, 
3L, 4L, 2L, 1L, 5L, 3L, 4L, 2L, 1L, 5L, 3L, 4L, 2L, 1L, 5L, 3L, 
4L, 2L, 1L, 5L, 3L, 4L, 2L, 1L), .Label = c("A", "B", "F", "H", 
"L"), class = "factor"), site = structure(c(1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 
5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L), .Label = c("A", "B", "C", 
"D", "E", "F"), class = "factor"), value = c(2.75, 0.5, 0.25, 
-4.125, -3.375, 3.78125, 1.375, 0.625, -10.6875, -6.34375, 4.28, 
2.065, 0.68, -12.1, -10.75, 8.583333333, 4.541666667, 2.166666667, 
-10.70833333, -4.25, 7.35, 4, 1.8, -13.95, -5.175, 1.933333333, 
1.245833333, 0.641666667, -11.16666667, -2.291666667)), .Names = c("horizon", 
"site", "value"), class = "data.frame", row.names = c(NA, -30L
))

现在我尝试通过首先指定土层水平的顺序(即从地上到地下的视野)来绘制数据:

require(ggplot2); require(dplyr)
df %>% 
  mutate(horizon = factor(horizon, levels = c("L","F","H","A","B")))  %>% 
  ggplot(aes(site, value)) + geom_col(aes(fill = horizon)) + labs(y = "Soil depth (cm)")

enter image description here

适用于LFH,但不适用于AB(地下,即负值)。它可能不起作用的原因是堆叠的条形从最大到最小排序site(分别对于正值和负值),然后以从上到下的方式堆叠。它是否正确?如果是这样,那么对于我的正面价值而言,传说与我认为的堆积条形相匹配只是巧合。

我想要实现的是在图例中堆叠符合顺序(从上到下)的条形图,因此在横截面视图中查看它时的土壤剖面并且我不确定如何接近这个。

我确实尝试改变一般的排序行为,但它产生了与上面相同的情节:

df %>% 
  mutate(horizon = factor(horizon, levels = c("L","F","H","A","B")))  %>% 
  arrange(desc(value)) %>% 
  ggplot(aes(site, value)) + geom_col(aes(fill=horizon)) + labs(y = "Soil depth (cm)")

df %>% 
  mutate(horizon = factor(horizon, levels = c("L","F","H","A","B")))  %>% 
  arrange(value) %>% 
  ggplot(aes(site, value)) + geom_col(aes(fill=horizon)) + labs(y = "Soil depth (cm)")

我可能需要分别对正值和负值进行排序,分别是降序和升序?

1 个答案:

答案 0 :(得分:2)

根据相应因子的水平对堆积条形图进行排序。潜在问题出现在负值反向堆叠(从负顶部朝向0)。为了说明问题,让所有的值都为负:

protocol Component {
    associatedtype Message
    mutating func send(msg: Message) -> [SideEffect<Message>]
}

struct State: Component {

    var something: String

    enum Message {
        case downloadSomething
        case receiveResponse(String)
    }

    mutating func send(msg: Message) -> [SideEffect<Message>] {
        switch msg {
        case .downloadSomething:
            let sideEffect = RequestSideEffect(
                request: Request(mock: "foo"), nextMessage: Message.receiveResponse
            )
            return [.sendRequest(sideEffect)]
        case .receiveResponse(let response):
            something = response
            return []
        }
    }
}

var s = State(something: "hello")
let sideEffects = s.send(msg: .downloadSomething)

for case .sendRequest(let sideEffect) in sideEffects {
    sideEffect.doRequest {
        _ = s.send(msg: $0) // no side effects expected
        print(s) // State(something: "foo")
    }
}

enter image description here

解决方法是指定不同级别的顺序,这将导致所需的填充顺序(在这种情况下为df %>% mutate(horizon = factor(horizon, levels = c("L","F","H","B","A"))) %>% ggplot(aes(site, value - 20)) + geom_col(aes(fill = horizon)) + labs(y = "Soil depth (cm)") )并使用levels = c("L","F","H","B","A")手动调整图例:

scale_fill_discrete

enter image description here