【ggplot】复杂柱状图:自定义颜色、标签、位置、坐标轴和主题

一直想有机会好好梳理下ggplot的图形,但是一般情况下ggplot常用的图形还是一些线图和柱状图,但是使用ggplot的好处(对比excel)就是R在处理大数据可以不用切换软件直接截取,但是坏处就是相对excel的某些时刻略有复杂,但是如果ggplot连excel的基本画图效率都比不过的话,也就失去了存在的意义。

简单的图形当然ggplot官方文档中就有,主要呈现以下复杂的ggplot的柱状图。首先还是载入下我的ggplot主题:

因为工作需要,ppt的模板都有固定颜色,这边颜色设定如下:

windowsFonts(A=windowsFont('等线'),B=windowsFont('微软雅黑'))
par(family='A')
pptblue<-rgb(r=16,g=77,b=96,maxColorValue = 255)
pptgrey<-rgb(r=107,g=107,b=107,maxColorValue = 255)
pptred<-rgb(r=233,g=77,b=96,maxColorValue = 255)
ppttea<-rgb(r=198,g=96,b=52,maxColorValue = 255)
pptdark<-rgb(r=69,g=87,b=101,maxColorValue = 255)
pptbg<-rgb(r=242,g=242,b=242,maxColorValue = 255)
par(bg=pptbg)
par(bty='l')
par(mar=c(4,5,4,6))

然后是对应颜色的主题:

theme1<-theme_bw()+theme(legend.position = 'top', #图例位置
                         text=element_text(family='A'), #字体
                         panel.background=element_rect(pptbg), #画布背景颜色
                         plot.background=element_rect(pptbg), #图形背景颜色
                         plot.title = element_text(hjust=0.5,size=16,vjust=0.5), #标题位置
                         panel.border=element_blank(),#图形边界
                         panel.grid.major=element_line(colour='lightgrey',linetype="dashed"), #网格线
                         panel.grid.minor=element_blank(), #次级网格线
                         legend.title=element_text(size=10,colour='black',family='A',vjust=-0.5), #图例标题
                         legend.text=element_text(size=10,colour='black',family='A'), #图例文字
                         legend.background =element_rect(pptbg),#图例背景
                         axis.text=element_text(size=12,colour="black",family='A'), #坐标轴文字
                         strip.text=element_text(size=12,colour="black",family='A'),#分面文字
                         strip.background=element_blank(),#分面的背景
                         axis.line = element_line(size=0.5, colour = 'black'), #轴颜色大小
                         panel.spacing=unit(10,'mm') #画布大小

这个主题没啥好说的,就是改了下图例的位置,文字的字体等;

ok,背景主题设置完毕,下面看下如何做柱状图:

数据集还是选择iris数据集。

先看下iris数据集

head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1          5.1         3.5          1.4         0.2
2          4.9         3.0          1.4         0.2
3          4.7         3.2          1.3         0.2
4          4.6         3.1          1.5         0.2
5          5.0         3.6          1.4         0.2
6          5.4         3.9          1.7         0.4
  Species
1  setosa
2  setosa
3  setosa
4  setosa
5  setosa
6  setosa

我们很熟悉的iris有四个变量,三个类别,如果我们第一个复杂的柱状图想看下三个类别分别的四个变量的占比和数值之类的信息,也就是我们需要三个柱子,每个柱子内部开始堆叠;

第一步,需要对数据进行整形,我们都知道ggplot需要长格式的数据,而且我们看分布,其实就是看一个求和,那么:

library(data.table)
iris1<-melt(iris,
            id.vars='Species',
            measure.vars=c('Sepal.Length','Sepal.Width','Petal.Length','Petal.Width'))
iris1<-data.table(iris1)

则iris1为:

iris1
       Species     variable value
  1:    setosa Sepal.Length   5.1
  2:    setosa Sepal.Length   4.9
  3:    setosa Sepal.Length   4.7
  4:    setosa Sepal.Length   4.6
  5:    setosa Sepal.Length   5.0
 ---                             
596: virginica  Petal.Width   2.3
597: virginica  Petal.Width   1.9
598: virginica  Petal.Width   2.0
599: virginica  Petal.Width   2.3
600: virginica  Petal.Width   1.8

这次我们把每个变量都放在了variable这个里面,但是我们还需要进行求和:

iris1_1<-iris1[,list(sumvalue=sum(value)),by=list(Species,variable)]
setorder(iris1_1,Species)

最后整形后的是:

iris1_1
       Species     variable sumvalue
 1:     setosa Sepal.Length    250.3
 2:     setosa  Sepal.Width    171.4
 3:     setosa Petal.Length     73.1
 4:     setosa  Petal.Width     12.3
 5: versicolor Sepal.Length    296.8
 6: versicolor  Sepal.Width    138.5
 7: versicolor Petal.Length    213.0
 8: versicolor  Petal.Width     66.3
 9:  virginica Sepal.Length    329.4
10:  virginica  Sepal.Width    148.7
11:  virginica Petal.Length    277.6
12:  virginica  Petal.Width    101.3

也就是三类,每个类别四个值,为四个变量的加和。

下面需要调整下标签,因为ggplot的标签分两部分,第一部分是位置,第二部分是值;值很好说,但是位置默认是高度,也就是堆叠的高度。而我们这次需要不放在那个顶部,而是放在中部,所以这个位置需要手工调整下。

#设置标签的高度,累计的高度为堆叠上面的一半
iris1_2<-iris1_1[,label_y:=cumsum(sumvalue)-sumvalue/2,by=list(Species)]

然后画一个图:

ggplot(iris1_2,aes(x=Species,
                   y=sumvalue,
                   fill=variable))+
  geom_bar(stat='identity',
           position=position_stack(reverse=T))+ #本来不用reverse是从上到下,反过来
  theme1+
  geom_text(aes(x=Species,y=label_y,label=sumvalue),
            position='identity',  #既然已经算出来label高度了,就不能stack
            color='white')+
  ggtitle('堆叠柱状图')+
  scale_fill_manual(name='图例', #图例项(或者用scale_fill_discrete)
                    labels=c('1-SL','2-SW','3-PL','4-PW'), #图例标签
                    values=c('darkgreen','red','darkblue','black'))+ #颜色
  scale_x_discrete(name='类别', #x轴坐标名称
                   labels=c('1-Setosa','2-Versicolor','3-Virginica'))+ #离散的标签
  scale_y_continuous(name='值', #y轴坐标名称
                     breaks=seq(0,1000,100),
                     limits=c(0,900)) #连续的标签和坐标轴

图形为:
这里写图片描述

除了堆叠柱状图,还有一个常用的就是普通柱状图,也就是并列摆放的类型。

在这个图中,我们可以自定义图例、文字颜色和坐标轴,如下:

ggplot(iris1_2,aes(x=factor(Species,
                            levels=levels(iris1_2$Species)[c(3,2,1)]),
                   y=sumvalue,
                   fill=factor(variable,
                               levels=levels(iris1_2$variable)[c(4,3,2,1)])))+
  geom_bar(stat='identity',
           position=position_dodge())+ #本来不用reverse是从上到下,反过来
  theme1+
  geom_text(aes(x=Species,y=sumvalue+20,label=sumvalue,
                color=factor(variable,
                             levels=levels(iris1_2$variable)[c(4,3,2,1)])),#和fill的一致
            position=position_dodge(width=0.9),
            show.legend = F)+#showlegend 隐藏文字的图例
  ggtitle('柱状图')+
  scale_fill_discrete(name='图例', #图例项(或者用scale_fill_discrete)
                      labels=levels(iris1_2$variable)[c(4,3,2,1)])+ #颜色
  scale_x_discrete(name='类别', #x轴坐标名称
                   labels=levels(iris1_2$Species)[c(3,2,1)])+ #离散的标签
  scale_y_continuous(name='值', #y轴坐标名称
                     breaks=seq(0,400,50),
                     limits=c(0,400))#连续的标签和坐标轴

对应的图形是:

这里写图片描述

  • 17
    点赞
  • 130
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值