在反方向创建水平条形图

时间:2017-09-21 10:48:02

标签: r ggplot2 bar-chart

我试图做一个金字塔 - "喜欢"在R中的情节,我想我很接近。我知道有一些函数,比如plotrix' pyramid.plot,但我想要做的并不是一个真正的金字塔情节。在金字塔图中,中间有文本标签,与左侧和右侧的条形成对齐。相反,我想做的是有两列文字,条形图离开它们。

我正在使用ggplot(但我想我不必)和multiplot函数。一个最小的例子是这样的:

mtcars$`car name` <- rownames(mtcars)
obj_a <- ggplot (mtcars, aes (x=`car name`, y=mpg))
obj_a <- obj_a + geom_bar (position = position_dodge(), stat="identity")
obj_a <- obj_a + coord_flip () 
obj_a <- obj_a + xlab ("")

USArrests$`states` <- rownames(USArrests)
obj_b <- ggplot (USArrests, aes (x=`states`, y=UrbanPop))
obj_b <- obj_b + geom_bar (position = position_dodge(), stat="identity")
obj_b <- obj_b + coord_flip () 
obj_b <- obj_b + xlab ("")

multiplot (obj_a, obj_b, cols=2)

看起来像这样:

Example graph

我想我想要的只是翻转左半边以便每行(从左到右):左栏,车型,州名,右栏。 (我制作的图表将在两半中具有相同的行数,因此它看起来不会那么局促。)但是,重点是,有两列文本,而不是一列。

当然,由于两半都是相互独立的,我真正的问题是我不知道如何制作左半部分。 (一个条形图,条形图反方向。)但我想我也会解释我想要做的事情......

提前谢谢!

3 个答案:

答案 0 :(得分:4)

您可以将{mp}值设置为obj_a为负,&amp;将汽车名称轴定位在另一侧:

ggplot (mtcars, aes (x=`car name`, y=-mpg)) +         # y takes on negative values
  geom_bar (position = position_dodge(), stat = "identity") + 
  coord_flip () + 
  scale_x_discrete(name = "", position = "top") +     # x axis (before coord_flip) on opposite side
  scale_y_continuous(name = "mpg",
                     breaks = seq(0, -30, by = -10),  # y axis values (before coord_flip) 
                     labels = seq(0,  30, by =  10))  # show non-negative values

obj_a

答案 1 :(得分:2)

似乎pyramid.plot已经完成了你所需要的。使用他们的例子:

xy.pop<-c(3.2,3.5,3.6,3.6,3.5,3.5,3.9,3.7,3.9,3.5,3.2,2.8,2.2,1.8,
          1.5,1.3,0.7,0.4)
xx.pop<-c(3.2,3.4,3.5,3.5,3.5,3.7,4,3.8,3.9,3.6,3.2,2.5,2,1.7,1.5,
          1.3,1,0.8)
agelabels<-c("0-4","5-9","10-14","15-19","20-24","25-29","30-34",
             "35-39","40-44","45-49","50-54","55-59","60-64","65-69","70-74",
             "75-79","80-44","85+")
mcol<-color.gradient(c(0,0,0.5,1),c(0,0,0.5,1),c(1,1,0.5,1),18)
fcol<-color.gradient(c(1,1,0.5,1),c(0.5,0.5,0.5,1),c(0.5,0.5,0.5,1),18)
par(mar=pyramid.plot(xy.pop,xx.pop,labels=agelabels,
                     main="Australian population pyramid 2002",lxcol=mcol,rxcol=fcol,
                     gap=0.5,show.values=TRUE))
# three column matrices
avtemp<-c(seq(11,2,by=-1),rep(2:6,each=2),seq(11,2,by=-1))
malecook<-matrix(avtemp+sample(-2:2,30,TRUE),ncol=3)
femalecook<-matrix(avtemp+sample(-2:2,30,TRUE),ncol=3)



# *** Make agegrps a two column data frame with the labels ***

# group by age 
agegrps<-data.frame(c("0","11","21","31","41","51",
           "61-70","71-80","81-90","91+"),
           c("10","20","30","40","50","60",
             "70","80","90","91"))


oldmar<-pyramid.plot(malecook,femalecook,labels=agegrps,
                     unit="Bowls per month",lxcol=c("#ff0000","#eeee88","#0000ff"),
                     rxcol=c("#ff0000","#eeee88","#0000ff"),laxlab=c(0,10,20,30),
                     raxlab=c(0,10,20,30),top.labels=c("Males","Age","Females"),gap=4,
                     do.first="plot_bg(\"#eedd55\")")
# put a box around it
box()
# give it a title
mtext("Porridge temperature by age and sex of bear",3,2,cex=1.5)
# stick in a legend
legend(par("usr")[1],11,c("Too hot","Just right","Too cold"),
       fill=c("#ff0000","#eeee88","#0000ff"))
# don't forget to restore the margins and background
par(mar=oldmar,bg="transparent")

结果: enter image description here

答案 2 :(得分:1)

您可以添加+ scale_y_reverse()而不是取反变量,该值在翻转后变为x

这样,您不必手动设置轴标签。

您仍然需要按照the answer by user Z.Lin中的建议更改x轴标签的位置 例如

library(ggplot2)

mtcars$`car name` <- rownames(mtcars)
ggplot (mtcars, aes (x=`car name`, y=mpg)) +
  geom_bar (position = position_dodge(), stat="identity") +
  scale_y_reverse () +
  scale_x_discrete(name = "", position = "top") +
  coord_flip () 

reprex package(v0.3.0)于2020-04-09创建