R語(yǔ)言實(shí)現(xiàn)ggplot重繪天貓雙十一銷售額曲線圖過程
前一段時(shí)間,很多人被這張圖刷屏了:
這張圖的來源是一篇名為 “淘寶2009-2018年歷年雙11銷售額數(shù)據(jù)造假” 的文章。圖中散點(diǎn)為天貓雙十一銷售額數(shù)據(jù),曲線為原作者擬合的回歸線。乍一看散點(diǎn)完美地分布在曲線上,原作者便直接聲稱:“淘寶雙十一銷售額數(shù)據(jù)造假!不可能有這么完美的擬合!” 可事實(shí)真的是這樣嗎?
作為一個(gè)熱愛畫畫的博主,我們先不來考慮這個(gè)問題,直接來試著在 R 中繪制出上圖,一個(gè)更好看版本的上圖。
Let's start
溫馨小提示:在這篇博客中,你可以學(xué)會(huì)下述 ggplot
的繪圖小技巧:
如何在圖像中擬合二次曲線;
如何在圖像中添加文本或自適應(yīng)地添加文本;
如何刪除一些不必要的背景線;
還有一些常規(guī)操作:換主題、改刻度、改顏色等等… …
偷偷放個(gè)最終成果:
輸入數(shù)據(jù)
首先我們查到具體每一年的天貓銷售額數(shù)據(jù),然后在 R 中構(gòu)建 data frame
.
year <- 2009:2019 sales <- c(0.5, 9.36, 52, 191, 350, 571, 912, 1207, 1682, 2135, 2684) dat_sales <- data.frame(year = year, sales = sales)
由于我們想重點(diǎn)凸顯出 2019 年的具體表現(xiàn),所以我們還需要添加一列 index 表示是否為 2019 年(非 2019 年為 1
, 2019 年為 2
):
dat_sales$ind <- factor(c(rep(x = 1, 10), 2))
數(shù)據(jù)框長(zhǎng)著如下這樣:
year sales ind 1 2009 0.50 1 2 2010 9.36 1 3 2011 52.00 1 4 2012 191.00 1 5 2013 350.00 1 6 2014 571.00 1 7 2015 912.00 1 8 2016 1207.00 1 9 2017 1682.00 1 10 2018 2135.00 1 11 2019 2684.00 2
好啦,有了上述數(shù)據(jù)框,我們就可以開始進(jìn)行 ggplot
的繪圖了!
粗略繪圖
首先我們就用默認(rèn)參數(shù)畫出散點(diǎn)變化趨勢(shì),同時(shí) 2019 年標(biāo)注出不一樣的顏色:
library(ggplot2) ggplot(dat = dat_sales) + geom_point(aes(x = year, y = sales, col = ind))
但是這樣的繪圖有很多問題:缺少標(biāo)題,坐標(biāo)軸的標(biāo)題改中文,x 軸的顯示不是離散的年份,散點(diǎn)過小,圖例問題等等問題,我們先一步一步來進(jìn)行完善。
完善散點(diǎn)圖
ggplot(dat = dat_sales) + geom_point(aes(x = year, y = sales, col = ind), size = 4) + scale_x_continuous(breaks = 2009:2019, labels = 2009:2019) + labs(title = "2009 - 2019 年銷售額", x = "年份", y = "銷售額 (億元)") + theme(legend.position = "none", plot.title = element_text(hjust = 0.5))
其中,size = 4
, 表示將散點(diǎn)進(jìn)行放大,具體的尺寸可以自己進(jìn)行設(shè)置; breaks = 2009:2019
表示原本數(shù)據(jù)集中在 x 軸上對(duì)應(yīng)的值; labels = 2009:2019
表示映射到圖像上 x 軸的值; legend.position = "none"
表示取消 legend 顯示。
強(qiáng)調(diào):這里為了顯示年份,其實(shí)可以采用將年份轉(zhuǎn)換成 factor 型的方法,但由于我們還需要使用年份數(shù)據(jù)進(jìn)行曲線擬合,若轉(zhuǎn)化成 factor 會(huì)使得曲線擬合失敗,因此我們采用稍微復(fù)雜一些的修改 x 軸刻度的方法。
添加擬合曲線
下面我們就開始添加二次函數(shù)擬合曲線:
ggplot(dat = dat_sales) + geom_point(aes(x = year, y = sales, col = ind), size = 4) + geom_smooth(aes(x = year, y = sales), se = FALSE, method = "lm", formula = y ~ x + I(x^2), size = 2) + scale_x_continuous(breaks = 2009:2019, labels = 2009:2019) + labs(title = "2009 - 2019 年銷售額", x = "年份", y = "銷售額 (億元)") + theme(legend.position = "none", plot.title = element_text(hjust = 0.5))
在 ggplot
中通常都是使用 geom_smooth
來進(jìn)行曲線或者直線的擬合,對(duì)于線性、二次、三次函數(shù),我們都是使用 method = "lm"
; se = FALSE
表示不顯示置信區(qū)間; formula = y ~ x + I(x^2)
表示使用二次函數(shù)進(jìn)行擬合; 最后的 size = 2
表示調(diào)整線的粗細(xì)。
在散點(diǎn)上添加銷售額
可以發(fā)現(xiàn),這樣的曲線只能看出趨勢(shì),但是卻看不出每年的具體銷售額,所以接下來我們嘗試在圖像的每個(gè)散點(diǎn)加上具體的銷售額:
# library(ggrepel) ggplot(dat = dat_sales) + geom_point(aes(x = year, y = sales, col = ind), size = 4) + geom_smooth(aes(x = year, y = sales), se = FALSE, method = "lm", formula = y ~ x + I(x^2), size = 2) + geom_text(aes(x = year, y = sales, label = sales), hjust = 0.5, vjust = -1) + # geom_text_repel(aes(x = year, y = sales, label = sales)) + ylim(0, 3000) + scale_x_continuous(breaks = 2009:2019, labels = 2009:2019) + labs(title = "2009 - 2019 年銷售額", x = "年份", y = "銷售額 (億元)") + theme(legend.position = "none", plot.title = element_text(hjust = 0.5))
當(dāng)我們需要在繪圖中添加文本時(shí),通??梢允褂?geom_text
函數(shù),然后 aes(label = )
中設(shè)定需要顯示的變量名稱,最后的 hjust = 0.5, vjust = -1
表示調(diào)整顯示的相對(duì)位置,前者表示水平位置,后者表示垂直位置,這個(gè)根據(jù)繪圖的不同需要自己進(jìn)行手動(dòng)調(diào)整。
同時(shí),2019 年的銷售額較高,如果不調(diào)整 y 軸的顯示范圍,最上面顯示的銷售額 2684 會(huì)被遮擋,所以我們添加了 ylim(0, 3000)
。
另外,細(xì)心的童鞋一定發(fā)現(xiàn)了,我們?cè)诖a中添加了兩行注釋,注釋的內(nèi)容同樣是添加文本的語(yǔ)句: geom_text_repel(aes(x = year, y = sales, label = sales))
,這個(gè)語(yǔ)句可以自適應(yīng)地調(diào)整每個(gè)文本顯示內(nèi)容,使文本不會(huì)擋住我們的散點(diǎn)和曲線,這個(gè)函數(shù)在包 ggrepel
中。這里之所以是因?yàn)檫@個(gè)方式大多用于圖像中散點(diǎn)比較多,比較亂的情況,如果在此幅圖中使用,會(huì)使得銷售額的文本顯示略顯混亂。
刪除不必要的背景線
再細(xì)心一些的童鞋可能觀察到了,背景的網(wǎng)格圖,在 x 軸每?jī)蓚€(gè)年份之間都有一根垂直線,這個(gè)垂直線是毫無意義的。這時(shí)我們不禁要問,是否有方法能夠?qū)⑦@根線消去呢?
答案是肯定的:
ggplot(dat = dat_sales) + geom_point(aes(x = year, y = sales, col = ind), size = 4) + geom_smooth(aes(x = year, y = sales), se = FALSE, method = "lm", formula = y ~ x + I(x^2), size = 2) + geom_text(aes(x = year, y = sales, label = sales), hjust = 0.5, vjust = -1) + ylim(0, 3000) + scale_x_continuous(breaks = 2009:2019, labels = 2009:2019) + labs(title = "2009 - 2019 年銷售額", x = "年份", y = "銷售額 (億元)") + theme(panel.grid.minor = element_blank(), legend.position = "none", plot.title = element_text(hjust = 0.5))
修改起來其實(shí)也不難,可以發(fā)現(xiàn),每個(gè)年份對(duì)應(yīng)的垂直線叫做 major
,而年份沒對(duì)應(yīng)到的網(wǎng)格線叫做 minor
,因此我們直接在 theme
中添加 panel.grid.minor = element_blank()
即可。
終極美化
到這里,我們的基本元素的拼湊已經(jīng)告一段落了,但是整體圖看起來依舊是不夠美觀,所以接下來我們?cè)龠M(jìn)行一些操作來美化繪圖,最終代碼與結(jié)果如下:
ggplot(dat = dat_sales, aes(x = year, y = sales)) + geom_smooth(se = FALSE, method = "lm", formula = y ~ x + I(x^2), size = 2, col = "#b3cde3") + geom_point(aes(col = ind), size = 4) + ylim(0, 3000) + geom_text(aes(label = sales), hjust = 0.5, vjust = -1) + scale_x_continuous(breaks = 2009:2019, labels = 2009:2019) + labs(title = "2009 - 2019 年銷售額", x = "年份", y = "銷售額 (億元)") + theme_bw(base_family = "Times") + theme(legend.position = "none", panel.grid.minor = element_blank(), panel.border = element_blank(), plot.title = element_text(hjust = 0.5))
這里其實(shí)做了一些細(xì)節(jié)的調(diào)整,首先先繪制擬合曲線,再繪制散點(diǎn),這樣散點(diǎn)就會(huì)在曲線的上方,這樣看起來會(huì)更加的美觀。其次改變了擬合曲線的顏色:col = "#b3cde3"
,改變了繪圖的主題:theme_bw(base_family = "Times")
,刪除了丑丑的邊框:panel.border = element_blank()
。
至此,我們美美的繪圖重構(gòu)就完成了!
小作業(yè)
最后,感興趣的童鞋不妨將我們圖中的二次擬合曲線替換成三次函數(shù)擬合,或者兩者均添加,然后修改一下透明度,使得兩條線都能看見一部分。
以上就是ggplot繪制天貓雙十一銷售額曲線圖實(shí)現(xiàn)過程的詳細(xì)內(nèi)容,更多關(guān)于ggplot繪制天貓雙十一銷售額的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用R語(yǔ)言繪制散點(diǎn)圖結(jié)合邊際分布圖教程
這篇文章主要介紹了使用R語(yǔ)言利用ggplot繪制散點(diǎn)圖,并且在圖像的兩邊繪制邊際分布圖(包括邊際直方圖與邊際密度函數(shù))我們這里介紹兩種方法進(jìn)行繪制2021-11-11R語(yǔ)言實(shí)現(xiàn)用cbind合并兩列數(shù)據(jù)
這篇文章主要介紹了R語(yǔ)言實(shí)現(xiàn)用cbind合并兩列數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04R語(yǔ)言繪圖公式與變量對(duì)象混合拼接實(shí)現(xiàn)方法
這篇文章主要為大家介紹了R語(yǔ)言繪圖中的公式如何與變量對(duì)象混合拼接的實(shí)現(xiàn)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11R語(yǔ)言-實(shí)現(xiàn)提取包含某字符串的行變量
這篇文章主要介紹了R語(yǔ)言-實(shí)現(xiàn)提取包含某字符串的行變量,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-04-04