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: ggplot2

R里畫圖第一個想到的是用ggplot2,覺的就是一個柱狀圖的layer加上一個折線圖就好了。但是想起來容易,操作起來卻挺困難。第一個是雙坐標軸的問題。這個問題無解,因為據說ggplot2的作者不喜歡雙坐標軸,覺得會誤導讀者。那折線圖就不要次坐標了吧,也不是不可以。然后把小數據映射到大數據的量級,如100%對應max(降水量),避免百分比的量級太小而在圖片上看不清。然后是添加圖例。柱狀圖和折線圖可以單獨添加圖例,但是兩個會添加在同一個位置并且彼此重疊。因為legend的position是通過theme來調節的,不能分別作用于柱狀圖和折線圖。目前我還沒找到解決方法,希望高人指點。我能做到的就是下圖這樣了:

代碼

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$humid
![excel.jpg](http://upload-images.jianshu.io/upload_images/4006139-cde6c9d7d654bb1c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
ity,
      itemStyle = list(
        normal=list( label = list(show = TRUE, formatter= JS("function(c){return Math.floor(c.value  * 10000)/100 + '%';}"))) # label保留小數點后兩位
      )
    )
  )
)
echart(barnline, width = 700, height =400)

效果截圖,動態效果可參考echarts示例:

一點體會:

  • 把echarts源代碼中所有的冒號:{}改成等號=, 所有的花括號{}改成list()
  • 不知道yihui接的是echarts2還是echarts3,在echarts3里顯示數據label是單獨的一條label語句,但R里要放到itemStyle中,否則報錯。
  • 總的來說很方便,定制性很高。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 簡介 文章較長,點擊直達我的博客,瀏覽效果更好。本文內容基本是來源于STHDA,這是一份十分詳細的ggplot2使...
    taoyan閱讀 51,413評論 7 159
  • 這篇文章主要講述Echarts設置字體和線條的顏色相關操作筆記,希望文章對你有所幫助,主要是自己的在線筆記吧。我在...
    藍色夢想家閱讀 10,078評論 1 1
  • 一大早醒來,沖一杯淡淡的苦咖,坐在飄窗旁的椅子上,靠著窗邊,打開簡書看著大家的文章,就像是每日必須完成的事情一樣。...
    Tom_說閱讀 458評論 9 2
  • 臨摹靳東,第四遍了,依然差距很大。
    知更鳥I閱讀 273評論 1 1
  • 今天傍晚出門吃飯,我穿了一條橙紅色的短裙剛好配自己非常喜歡的一件黑色羊絨長大衣。 因為好久沒有穿過膝長靴了,靴子需...
    楚浛閱讀 1,046評論 8 19