R+Echarts画双坐标轴折柱混合图—科研工具箱

请关注公众号【叨客学习资料】 在使用网站的过程中有疑问,请来公众号进行反馈哦

柱状图和折线图的组合图是excel里很容易实现的一个功能,日常报表里也经常使用这类型的图。最近想用Rmarkdown自动生成日报并直接发邮件,但却被这个简单的图难住了。

先造一些数据,没有实际意义。柱状图要显示绝对值,折线图要显示百分比。formattable包可以把小数显示成百分比而保留其numeric的类型。

library(formattable)
# test data 数据均为捏造
y<-data.frame(date=c(\'1月\',\'2月\',\'3月\',\'4月\',\'5月\',\'6月\',\'7月\'),
              waterfall = c(2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6),
              humidity=percent(c(0.5012, 0.25, 0.1818, 0.3333, 0.5385, 0.9091, 0.7273)))

在excel中的效果如下图,有点丑,别介意,大致就是这么个意思:

图片[1]-R+Echarts画双坐标轴折柱混合图—科研工具箱-叨客学习资料网
 
尝试1: ggplot2

R里画图第一个想到的是用ggplot2,觉的就是一个柱状图的layer加上一个折线图就好了。但是想起来容易,操作起来却挺困难。第一个是双坐标轴的问题。这个问题无解,因为据说ggplot2的作者不喜欢双坐标轴,觉得会误导读者。那折线图就不要次坐标了吧,也不是不可以。然后把小数据映射到大数据的量级,如100%对应max(降水量),避免百分比的量级太小而在图片上看不清。然后是添加图例。柱状图和折线图可以单独添加图例,但是两个会添加在同一个位置并且彼此重叠。因为legend的position是通过theme来调节的,不能分别作用于柱状图和折线图。目前我还没找到解决方法,希望高人指点。我能做到的就是下图这样了:

图片[2]-R+Echarts画双坐标轴折柱混合图—科研工具箱-叨客学习资料网
 

代码

ggplot(y)+
  geom_bar(aes(x=y[1:7,1], y=y[1:7,2]), stat=\"identity\", width=.5, fill=\'#227487\')+
  ylim(c(0,200))+
  geom_text(aes(x=y[1:7,1], y=y[1:7,2], label=y[1:7,2]), vjust=-0.5)+
  geom_line(aes(x =y[1:7,1], y=y[1:7,3]*max(y[1:7,2]),linetype = \'湿度\' , group=1), size=1.2, color=\'#ca3e1c\')+
  # scale_colour_manual(values = c(\"湿度\"=\"red\")) +
  geom_point(aes(x =y[1:7,1], y=y[1:7,3]*max(y[1:7,2])), size=4, shape=21, fill=\'white\', color=\'#ca3e1c\')+
  geom_text(aes(x=y[1:7,1], y=y[1:7,3]*max(y[1:7,2]), 
                label=paste(y[1:7,3]*100, \'%\', sep=\'\')), vjust=-1)+
  xlab(\'\')+ylab(\'降雨量\')+
  theme(axis.text=element_text(size=12), axis.title=element_text(size=12),
        legend.title=element_blank(), 
        panel.background = element_rect(fill = \'white\', colour = \'white\'),
        legend.position=\"top\")+
  ggtitle(\'测试数据\')

双坐标轴还可以用R自带的plot来做,也有一个双坐标轴的包,但图都有点丑,所以没有再研究了。有兴趣可以看stackoverflow上的这篇 How can I plot with 2 different y-axes?

尝试2: recharts

recharts是R调用百度echarts的一个包,目前其实有两个包叫recharts,一个是yihui做的,另一个是taiyun的。taiyun的包里把echarts的各个图形分类别做了接口,代码简单,但是可定制的地方较少,比较适合不需要复杂图形的情况。yihui的包基本就是把js语言先用R的格式写,然后再翻译成js语言(我猜的),所以定制能力几乎和原生echats一样。我这里用的是yihui的包,注意安装时不要通过cran而是从github安装,因为从cran安装的recharts版本较低。

devtools::install_github(\"yihui/recharts\")

我用的echarts模版是它的折柱混合图。在默认的基础上改了bar和line的颜色,增加并格式化label,修改次坐标轴的label格式。

library(recharts)
barnline<-list(
  title = list(text = \'测试数据\'),
  tooltip = list(),
  legend = list(data=c(\'降水量\',\'湿度\')),
  xAxis= list(
    type= \'category\',
    data= y$date,
    splitLine = list(show=FALSE) # 删掉竖线
  ),
  yAxis= list(
    list(
      type= \'value\',
      name= \'降水量\',
      min= 0,
      max= ceiling(max(y$waterfall/10))*10,
      interval= ceiling(max(y$waterfall/10))*10/5,
      splitLine=list(
        show=FALSE # 删掉横线
      ) 
      #axisLabel= list (formatter= \'{value} ml\')
    ),
    list(
      type= \'value\',
      name= \'湿度\',
      min= 0,
      splitLine=list(
        show=FALSE
      ) ,
      max= 1,
      interval= 0.2 ,
      axisLabel= list(formatter= JS(\"function(value){return value * 100 + \'%\';}\"))
    )
  ),
  series = list(
    list(
      name=\"降水量\",
      type=\'bar\',
      data=y$waterfall,
      itemStyle = list(
        normal=list(color = \'#227487\', label = list(show = TRUE)) # set bar color and label
      )
    ),
    list(
      name=\'湿度\',
      type=\'line\',
      yAxisIndex= 1,
      data=y$humidity,
      itemStyle = list(
        normal=list( label = list(show = TRUE, formatter= JS(\"function(c){return Math.floor(c.value  * 10000)/100 + \'%\';}\"))) # label保留小数点后两位
      )
    )
  )
)
m<-echart(barnline, width = 700, height =400)
m
##保存为html文件
library(\"htmlwidgets\")
saveWidget(m, \"I:/temp.html\", selfcontained = FALSE)

效果截图,动态效果可参考echarts示例:

图片[3]-R+Echarts画双坐标轴折柱混合图—科研工具箱-叨客学习资料网
 

一点体会:

  • 把echarts源代码中所有的冒号:{}改成等号=, 所有的花括号{}改成list()
  • 不知道yihui接的是echarts2还是echarts3,在echarts3里显示数据label是单独的一条label语句,但R里要放到itemStyle中,否则报错。
  • 总的来说很方便,定制性很高。

更多相关设置请参考ECHARTShttps://echarts.apache.org/examples/zh/index.html

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
请输入有效评论哦,肆意灌水或者乱打评论是不会通过的,会影响您评论后获得资源哦~~
提交
头像

昵称

取消
昵称表情

    暂无评论内容