如何自定义双轴条形图?

How to customize dual axes barchart?

这是

的后续问题

我有 1 个猫和 3 个数值变量的 df。现在我想知道如何按 'cost' 的大小(由红线给出)从右到左对条形图进行排序。在我想自己手动指定每个条形的颜色之后,但找不到方法。另外,是否可以将这些数字(成本)放在方框内?

df <- data.frame (model  = c("A", "B", "C","D","E","F"),
                  share = c(12,20,15,9,60,20),
                  sale = c(16,25,18,14,67,28),
                  cost = c(14,19,28,24,57,28))

df_long <- df %>% 
  pivot_longer(
    cols = -model
  )



ggplot(df_long, aes(x = model, y= value, label=value))+
  geom_col(data = filter(df_long, name != "cost"), aes(fill=name), position = position_dodge())+
  scale_fill_manual(values = c("blue", "grey"))+
  geom_line(data = filter(df_long, name == "cost"), aes(color = name, group = 1), size = 0.5)+
  scale_color_manual(values = "red")+
  geom_point(data = filter(df_long, name == "cost"), size = 2)+
  geom_text(data = filter(df_long, name == "cost"), hjust=0, vjust=-0.5)+
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~., name ="Cost")
  )+
  theme_minimal()+
  theme(legend.title=element_blank())

modelcost 的顺序可以通过设置因子的水平来完成。将 geom_text 更改为 geom_label 创建框而不是纯粹显示文本。我不确定“。我自己手动指定每个条的颜色”是什么意思。你说的是填充吗?颜色现在由您的因素决定,可以通过 scale_fill_manual 更改,但您已经这样做了。

#data
df <- data.frame (model  = c("A", "B", "C","D","E","F"),
                  share = c(12,20,15,9,60,20),
                  sale = c(16,25,18,14,67,28),
                  cost = c(14,19,28,24,57,28))

#set levels of model by cost
df$model <- factor(df$model, levels = arrange(df, desc(df$cost))$model)

#set to long format
df_long <- df %>% 
  pivot_longer(
    cols = -model
  )

#plot (changed geom_text to geom_label)
ggplot(df_long, aes(x = model, y= value, label=value))+
  geom_col(data = filter(df_long, name != "cost"), aes(fill=name), position = position_dodge())+
  scale_fill_manual(values = c("blue", "grey"))+
  geom_line(data = filter(df_long, name == "cost"), aes(color = name, group = 1), size = 0.5)+
  scale_color_manual(values = "red")+
  geom_point(data = filter(df_long, name == "cost"), size = 2)+
  geom_label(data = filter(df_long, name == "cost"), hjust=0, vjust=-0.5)+
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~., name ="Cost")
  )+
  theme_minimal()+
  theme(legend.title=element_blank())

更新: 用你喜欢的颜色定义一个向量,然后使用 scale_fill_identity:


colors <- c("black","blue","black","green","black","orange",
            "black","pink","black", "yellow", "black","green")

library(tidyverse)

df_long <- df %>% 
  pivot_longer(
    cols = -model
  ) 


ggplot(df_long, aes(x = fct_reorder(model,desc(value)), y= value, label=value))+
  geom_col(data = filter(df_long, name != "cost"), aes(fill=colors), position = position_dodge())+
  scale_fill_identity()+
  geom_line(data = filter(df_long, name == "cost"), aes(color = name, group = 1), size = 1)+
  scale_color_manual(values = "red")+
  geom_point(data = filter(df_long, name == "cost"), size = 2)+
  geom_label(data = filter(df_long, name == "cost"), hjust=0, vjust=-1.5)+
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~., name ="Cost")
  )+
  theme_minimal()+
  theme(legend.title=element_blank())

第一个回答: 我们可以使用 forcats 包中的 fct_reorder 它位于 tidyverse

library(tidyverse)

df_long <- df %>% 
  pivot_longer(
    cols = -model
  ) 


ggplot(df_long, aes(x = fct_reorder(model, desc(value)), y= value, label=value))+
  geom_col(data = filter(df_long, name != "cost"), aes(fill=name), position = position_dodge())+
  scale_fill_manual(values = c("blue", "grey"))+
  geom_line(data = filter(df_long, name == "cost"), aes(color = name, group = 1), size = 1)+
  scale_color_manual(values = "red")+
  geom_point(data = filter(df_long, name == "cost"), size = 2)+
  geom_label(data = filter(df_long, name == "cost"), hjust=0, vjust=-0.5)+
  scale_y_continuous(
    name = "Sale and Share",
    sec.axis = sec_axis(~., name ="Cost")
  )+
  theme_minimal()+
  theme(legend.title=element_blank())