日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

chartcontrol饼状图属性设置_温故而知新,ggplot2 饼图的几点笔记

發(fā)布時間:2025/3/20 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 chartcontrol饼状图属性设置_温故而知新,ggplot2 饼图的几点笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

其實 ggplot2 并沒有類似于 geom_pie() 這樣的函數(shù)實現(xiàn)餅圖的繪制,它是由 ?geom_bar() 柱狀圖經(jīng)過 ?coord_polar() 極坐標(biāo)彎曲從而得到的。
對于為什么 ggplot2 中沒有專門用于餅圖繪制的函,有人說:“柱狀圖的高度,對應(yīng)于餅圖的弧度,餅圖并不推薦,因為人類的眼睛比較弧度的能力比不上比較高度(柱狀圖)。” 關(guān)于餅狀圖被批評為可視化效果差,不推薦在 R 社區(qū)中使用的文章在網(wǎng)絡(luò)也有不少,感興趣的可以去搜一下。

不管怎么說,學(xué)習(xí)一下總不是壞事,趁著一些客戶剛好對餅圖有需求,重溫一下。

極坐標(biāo)系

極坐標(biāo)應(yīng)該是高中數(shù)學(xué)的知識,對我而言,基本都已經(jīng)忘光了,結(jié)合網(wǎng)上的一些資料重溫一下。

極坐標(biāo)是指在平面內(nèi)取一個定點 O,叫極點,引一條射線 Ox,叫做極軸,再選定一個長度單位和角度的正方向(通常取逆時針方向)。對于平面內(nèi)任何一點 M,用 ?ρ 表示線段 OM 的長度(有時也用 r 表示),θ 表示從 Ox 到 OM 的角度,ρ 叫做點 M 的極徑,θ 叫做點 M 的極角,有序數(shù)對 (ρ, θ) 就叫點 M 的極坐標(biāo),這樣建立的坐標(biāo)系叫做極坐標(biāo)系。通常情況下,M 的極徑坐標(biāo)單位為 1(長度單位),極角坐標(biāo)單位為 rad(或 °)。

極坐標(biāo)系中一個重要的特性是,平面直角坐標(biāo)中的任意一點,可以在極坐標(biāo)系中有無限種表達(dá)形式。通常來說,點(r, θ)可以任意表示為(r, θ ± n×360°)或 (?r, θ ± (2n + 1)180°),這里 n 是任意整數(shù)。如果某一點的 r 坐標(biāo)為 0,那么無論 θ 取何值,該點的位置都落在了極點上。

笛卡爾坐標(biāo)和極坐標(biāo)之間的轉(zhuǎn)換,請參考數(shù)學(xué)樂網(wǎng)站的《極坐標(biāo)與笛卡爾坐標(biāo)》一文,非常詳細(xì)直觀。

coord_polar

coord_polar() 是 ggplot2 中的極坐標(biāo)函數(shù),它可以彎曲橫縱坐標(biāo),使用這個函數(shù)做出蜘蛛圖或餅圖的效果。我在網(wǎng)絡(luò)上查了一下,比較少看到關(guān)于 coord_polar() 原理的介紹,只是在 ggplot2 的 Tidyverse 上發(fā)現(xiàn)了幾個例子。

library(ggpubr)
library(ggplot2)

df?"A",?"B",?"C"),?value?=?c(10,?50,?30))
p?"identity",?width=1,?colour="black")
g?"",?y=value,?fill=name))?+?geom_bar(stat="identity",?width=1,?colour="black")

用法

coord_polar() 主要有四個參數(shù):theta, start, direction 和 clip 。

coord_polar(theta?=?"x",?start?=?0,?direction?=?1,?clip?=?"on")
  • theta:variable to map angle to ( x or y ).

  • start:offset of starting point from 12 o'clock in radians.

  • direction:1, clockwise; -1, anticlockwise.

  • clip:Should drawing be clipped to the extent of the plot panel? A setting of "on" (the default) means yes, and a setting of "off" means no.

小知識:角度制 vs 弧度制


1度=π/180≈0.01745弧度,1弧度=180/π≈57.3度。

角的度量單位通常有兩種,一種是角度制,另一種就是弧度制。角度制,就是用角的大小來度量角的大小的方法。在角度制中,我們把周角的 1/360 看作 1 度,那么,半周就是 180 度,一周就是 360 度。由于 1 度的大小不因為圓的大小而改變,所以角度大小是一個與圓的半徑無關(guān)的量。
弧度制,顧名思義,就是用弧的長度來度量角的大小的方法。單位弧度定義為圓周上長度等于半徑的圓弧與圓心構(gòu)成的角。由于圓弧長短與圓半徑之比,不因為圓的大小而改變,所以弧度數(shù)也是一個與圓的半徑無關(guān)的量。角度以弧度給出時,通常不寫弧度單位,有時記為 rad 或 R。

參數(shù)示例

結(jié)合一些示例,理解一下 coord_polar() 的幾個參數(shù)。

  • theta="x"

x 軸極化,x 軸刻度值對應(yīng)扇形弧度,y 軸刻度值對應(yīng)圓環(huán)半徑。p 中由于 x 是等長的,所以 p1 每一個弧度為 60 度;p2 的每一個弧度為 360 度。

p1?"x")?+?labs(title="theta=\"x\"")
g1?"x")?+?labs(title="theta=\"x\"")
ggarrange(p,?g,?p1,?g1,?ncol=2,?nrow=2,?labels=c("p",?"g",?"p1",?"g1"))
  • theta="y"

y 軸極化,y 軸刻度值對應(yīng)扇形弧度,x 軸長度對應(yīng)扇形半徑。對于并列柱狀圖 p,以最大的 y 值作為 360 度的弧度,剩下的按比例類推,由于 p 中 A、B、C 是等長的,所以在 p1 中它們的半徑是 1:2:3。對于堆疊柱狀圖 g,把 y 值按照比例劃分弧度,因此它們的弧度比等于各自的 y 值比例。

p2?"y")?+?labs(title="theta=\"y\"")
g2?"y")?+?labs(title="theta=\"y\"")
ggarrange(p,?g,?p2,?g2,?ncol=2,?nrow=2,?labels=c("p",?"g",?"p2",?"g2"))
  • start=pi/6, direction=1

起始位置為距離 12 點針方向 30 度,順時針排列。

p3?"y",?start=pi/6,?direction=1)?+?labs(title="theta=\"x\",start=pi/6,direction=1")
g3?"y",?start=pi/6,?direction=1)?+?labs(title="theta=\"x\",start=pi/6,direction=1")
ggarrange(p,?g,?p3,?g3,?ncol=2,?nrow=2,?labels=c("p",?"g",?"p3",?"g3"))
  • start=pi/6, direction=-1

起始位置為距離 12 點針方向 30 度,逆時針排序。

p4?"y",?start=pi/6,?direction=-1)?+?labs(title="theta=\"y\",start=pi/6,direction=-1")
g4?"y",?start=pi/6,?direction=-1)?+?labs(title="theta=\"y\",start=pi/6,direction=-1")
ggarrange(p,?g,?p4,?g4,?ncol=2,?nrow=2,?labels=c("p",?"g",?"p4",?"g4"))
  • start=-pi/6, direction=1

起始位置為距離 12 點針方向負(fù) 30 度,順時針排序。

p5?"y",?start=-pi/6,?direction=1)?+?labs(title="theta=\"y\",start=-pi/6,direction=1")
g5?"y",?start=-pi/6,?direction=1)?+?labs(title="theta=\"y\",start=-pi/6,direction=1")
ggarrange(p,?g,?p5,?g5,?ncol=2,?nrow=2,?labels=c("p",?"g",?"p5",?"g5"))

Github 上有關(guān)于 coord-pola.r 的源碼,整個代碼只有 300 多行,有興趣的同學(xué)可以去研究一下,上面的理解如有不對的地方還請幫忙指正。

餅圖中添加文字的位置控制 - 借助公式

繪制餅圖的過程中,利用 ggplot2 的 geom_bar 結(jié)合 coord_polar 實現(xiàn)。

#?Load?ggplot2
library(ggplot2)

#?Create?Data
data?1:5],?value=c(13,7,9,21,2))

#?Basic?piechart
ggplot(data,?aes(x="",?y=value,?fill=group))?+
??geom_bar(stat="identity",?width=1)?+
??coord_polar("y",?start=0)

需要理解的點是餅圖的排布是按照 aes(fill) 的因子順序確定的。譬如數(shù)據(jù)如下:>?dat?1:5],?Num=c(90,?34,?56,?99,?15))
>?dat
??type?Num
1????A??90
2????B??34
3????C??56
4????D??99
5????E??15

必須根據(jù)數(shù)據(jù)先確定 mapping 中 aes(fill) 的因子順序,譬如這里會按照 dat$type 填充,這種非有序因子會基于字母順序來默認(rèn)其填充順序。

為了確定數(shù)據(jù)填充的先后,同時方便在不同區(qū)域上填寫上對應(yīng)數(shù)據(jù)的大小,所以會先去創(chuàng)建有序因子,從而使數(shù)據(jù)列 dat$Num 的自然順序和因子的順序在一定程度上一致(一致的同向?qū)?yīng)或反向?qū)?yīng))。譬如如下使方向一致:

dat$type?T)
dat$type
有序因子的結(jié)果則如下,和 dat$Num 的順序能夠一致上,不會出現(xiàn)對應(yīng)錯亂問題。[1]?A?B?C?D?E
Levels:?A?畫圖:p_pie?"",?y=dat[,2],?fill=dat[,1]))+
??geom_bar(stat="identity",?width=1)+
??coord_polar(theta="y",?direction=1)+
??scale_fill_brewer(palette?="Set3",?direction?=?1)+
??labs(x="",?y="",?fill="Type")+
??ggtitle(label?="test",?subtitle=NULL)
p_pie

結(jié)合下圖結(jié)果可以看出坐標(biāo)軸方向使順時針,而顏色設(shè)置 scale_fill_brewer(palette ="Set3",direction = 1) 設(shè)定了第一個顏色填充到第一個因子對應(yīng)的 “A” 上,這樣就反映出在圖片實際分布中數(shù)據(jù)和因子是反向?qū)?yīng)的。雖然在 dat 數(shù)據(jù)框中設(shè)置是順序一致方向相同的對應(yīng),但圖片分布中會改變。

小知識:scale_fill_brewer
scale_fill_brewer 是一個 ggplot2 和 RColorBrewer 關(guān)聯(lián)的一個擴展調(diào)色板,其他可用于 scale_fill_brewer 調(diào)色板的顏色包括:

Diverging????????BrBG,?PiYG,?PRGn,?PuOr,?RdBu,?RdGy,?RdYlBu,?RdYlGn,?Spectral
Qualitative?????Accent,?Dark2,?Paired,?Pastel1,?Pastel2,?Set1,?Set2,?Set3
Sequential???????Blues,?BuGn,?BuPu,?GnBu,?Greens,?Greys,?Oranges,?OrRd,?PuBu,?
????????????????????????PuBuGn,?PuRd,?Purples,?RdPu,?Reds,?YlGn,?YlGnBu,?YlOrBr,?YlOrRd

參考:https://ggplot2.tidyverse.org/reference/scale_brewer.html

結(jié)合圖片中反向?qū)?yīng)的關(guān)系,在 A 區(qū)塊上中間位置填充上對應(yīng)的文字 "Num:90",它的坐標(biāo)因該是 sum(dat$Num)-90 +90/2 ;如果是 B 區(qū)塊對應(yīng)的應(yīng)該坐標(biāo)為 sum(dat$Num)-90-34 +34/2 ,歸納為:

sum(dat\$Num)-cumsum(dat$Num)+dat$Num/2,即:>?sum(dat$Num)-cumsum(dat$Num)+dat$Num/2
[1]?249.0?187.0?142.0??64.5???7.5

小知識:R 語言 cumsum 函數(shù)cumsum 是 R 語言 base 包 cum 系列的一個函數(shù),它的功能是計算向量的累積和并返回。

cum 系列還有另外三個函數(shù):cumprod, cummin, cummax ,它們的作用分別是計算向量的累積的乘積、極小值、極大值,并返回。

#?對數(shù)值型向量求和
>?cumsum(1:10)????
[1]??1??3??6?10?15?21?28?36?45?55

#?對數(shù)值型矩陣求和,結(jié)果返回仍是向量
>?cumsum(matrix(1:12,?nrow?=?3))??
[1]??1??3??6?10?15?21?28?36?45?55?66?78

#?對數(shù)據(jù)框求和,返回結(jié)果仍然是數(shù)據(jù)框,cumsum?會對對每個變量進行求和處理
>?cumsum(data.frame(a?=?1:10,?b?=?21:30))??
???a???b
1???1??21
2???3??43
3???6??66
4??10??90
5??15?115
6??21?141
7??28?168
8??36?196
9??45?225
10?55?255

結(jié)合 geom_text(aes(x,y)) 的位置設(shè)置,保證中間文字填寫不會出錯:

p_pie=p_pie+
??geom_text(aes(x=1.2,y=sum(dat$Num)-cumsum(dat$Num)+dat$Num/2?,label=as.character(dat[,2])),size=3)
p_pie
如果最初構(gòu)建有序因子的方向和實際數(shù)據(jù)的方向反向?qū)?yīng)呢?dat$type=factor(dat$type,levels?=?rev(dat$type),order=T)
dat$type

p_pie=ggplot(dat,aes(x="",y=dat[,2],fill=dat[,1]))+
??geom_bar(stat="identity",width=1)+
??coord_polar(theta="y",direction=1)+
??scale_fill_brewer(palette?="Set3",direction?=?1)+
??labs(x="",y="",fill="Type")+
??ggtitle(label?="test",subtitle=NULL)
p_pie結(jié)合圖片可以知道,第一個因子 "E" 對應(yīng)了第一個顏色,不過從圖片顯示坐標(biāo)中可以看到,"A" 在前,而 "A" 在原始數(shù)據(jù) dat$Num 中對應(yīng)的數(shù)據(jù)也在前 90,這樣計算位置就會發(fā)生改變了,這時候 "A" 文字應(yīng)該對應(yīng) 90-90/2,文字 "B" 將對應(yīng) 90+34-34/2,…,歸納為 cumsum(dat$Num)-dat$Num/2 。>?cumsum(dat$Num)-dat$Num/2
[1]??45.0?107.0?152.0?229.5?286.5


而且圖例也是反向的,需要結(jié)合 guides(fill=guide_legend(reverse=T)) ,并且希望第一個顏色對應(yīng)最后一個因子 "A", scale_fill_brewer(palette ="Set3",direction = -1) :

dat$type=factor(dat$type,levels?=?rev(dat$type),order=T)
dat$type

p_pie=ggplot(dat,aes(x="",y=dat[,2],fill=dat[,1]))+
??geom_bar(stat="identity",width=1)+
??coord_polar(theta="y",direction=1)+
??scale_fill_brewer(palette?="Set3",direction?=?-1)+
??labs(x="",y="",fill="Type")+
??ggtitle(label?="test",subtitle=NULL)+
??guides(fill=guide_legend(reverse?=?T))+
??geom_text(aes(x=1.2,y=cumsum(dat$Num)-dat$Num/2?,label=as.character(dat[,2])),size=3)

p_pie

總結(jié)可知:ggplot2 在畫餅圖的過程中設(shè)定填充的因子方向總和圖片坐標(biāo)中的方向相反,不過因子的順序和數(shù)據(jù) dat$Num 的對應(yīng)關(guān)系是正向?qū)?yīng)或者反向?qū)?yīng),會影響相關(guān)區(qū)塊的中心位置值計算的方式,從而影響 geom_text 中文字定位。

餅圖中添加文字的位置控制(借助公式)部分的內(nèi)容主要參考了 Daitoue 在 OmicsClass 的一篇文章(詳見參考資料),OmicsClass 上還給出了不借助公式在餅圖中添加文字的位置控制,感興趣的同學(xué)也已點擊文章左下角 "閱讀原文" 進行閱讀。

sessionInfo 信息

本次學(xué)習(xí) R 和相關(guān)包版本信息。

>?sessionInfo()
R?version?3.6.2?(2019-12-12)
Platform:?x86_64-conda_cos6-linux-gnu?(64-bit)
Running?under:?CentOS?Linux?7?(Core)

Matrix?products:?default
BLAS/LAPACK:?/usr/local/software/miniconda3/lib/libopenblasp-r0.3.8.so

locale:
?[1]?LC_CTYPE=en_US.UTF-8???????LC_NUMERIC=C
?[3]?LC_TIME=en_US.UTF-8????????LC_COLLATE=en_US.UTF-8
?[5]?LC_MONETARY=en_US.UTF-8????LC_MESSAGES=en_US.UTF-8
?[7]?LC_PAPER=en_US.UTF-8???????LC_NAME=C
?[9]?LC_ADDRESS=C???????????????LC_TELEPHONE=C
[11]?LC_MEASUREMENT=en_US.UTF-8?LC_IDENTIFICATION=C

attached?base?packages:
[1]?stats?????graphics??grDevices?utils?????datasets??methods???base

other?attached?packages:
[1]?ggplot2_3.2.1

loaded?via?a?namespace?(and?not?attached):
?[1]?Rcpp_1.0.3?????????viridisLite_0.3.0??digest_0.6.25??????withr_2.1.2
?[5]?crayon_1.3.4???????dplyr_0.8.3????????assertthat_0.2.1???grid_3.6.2
?[9]?R6_2.4.0???????????gtable_0.3.0???????magrittr_1.5???????scales_1.0.0
[13]?pillar_1.4.3???????rlang_0.4.5????????lazyeval_0.2.2?????labeling_0.3
[17]?RColorBrewer_1.1-2?glue_1.3.1?????????purrr_0.3.2????????munsell_0.5.0
[21]?compiler_3.6.2?????pkgconfig_2.0.3????colorspace_1.4-1???tidyselect_0.2.5
[25]?tibble_2.1.3
>

FAQ:如何實現(xiàn) R 語言餅圖標(biāo)簽的 overlap 問題?

文章的最后,提個問題:有沒有通用的 R 包或者函數(shù),可以得到下面效果的餅圖?

參考資料

  • Daitoue,《餅圖 pie - ggplot2》,OmicsClass

  • Daitoue,《餅圖中添加文字的位置控制-ggplot2(非公式)》,OmicsClass

特別聲明:文章中關(guān)于"餅圖中添加文字的位置控制(借助公式與非公式)" 部分內(nèi)容,主要參考了 Daitoue 在 OmicsClass 的兩篇文章(詳見參考資料),在這里特別感謝一下。參考的文章主要用于學(xué)習(xí)交流目的,如有任何侵權(quán),請第一時間與我聯(lián)系。

戳原文,更有料!

總結(jié)

以上是生活随笔為你收集整理的chartcontrol饼状图属性设置_温故而知新,ggplot2 饼图的几点笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。