質問するログイン新規登録

回答編集履歴

1

Update

2022/01/03 07:47

投稿

melian
melian

スコア21464

answer CHANGED
@@ -1,19 +1,121 @@
1
- 外側からり半径(`radius`)の大きな `pie chart` から描いてい、という手順
1
+ `pie` function のソースコードを見ると以下の部分でラベルを描画していす。`lines()``tick`(いわゆるヒゲ)`text()` でラベルを描いているわけですが`1.05` か `1.1` という係数を書き替えます
2
2
  ```r
3
+ if (!is.na(lab) && nzchar(lab)) {
4
+ lines(c(1, 1.05) * P$x, c(1, 1.05) * P$y)
5
+ text(1.1 * P$x, 1.1 * P$y, labels[i], xpd = TRUE,
3
- library(RColorBrewer)
6
+ adj = ifelse(P$x < 0, 1, 0), ...)
7
+ }
8
+ ```
4
9
 
5
- cols <- brewer.pal(length(islands), "Set2")
6
- pie(islands, radius=0.9, clockwise=TRUE, border="white", labels=head(names(islands),4), col=cols)
10
+ `R` では monkey patching などということはできないので、`pie()` function のコードをコピペして別名で定義します。そして、`pie chart` の内側にラベルを描くため、先程の係数を調整します。
11
+ ```r
12
+ if (!is.na(lab) && nzchar(lab)) {
13
+ lines(c(1, 0.95) * P$x, c(1, 0.95) * P$y)
14
+ text(0.92 * P$x, 0.85 * P$y, labels[i], xpd = TRUE,
15
+ adj = ifelse(P$x > 0, 1, 0), ...)
16
+ }
17
+ ```
7
18
 
19
+ 以下、`pie315` という関数名を付けて使います。
20
+ ```r
21
+ pie315 <- function (x, labels = names(x), edges = 200, radius = 0.8, clockwise = FALSE,
22
+ init.angle = if (clockwise) 90 else 0, density = NULL, angle = 45,
23
+ col = NULL, border = NULL, lty = NULL, main = NULL, ...)
24
+ {
25
+ if (!is.numeric(x) || any(is.na(x) | x < 0))
26
+ stop("'x' values must be positive.")
27
+ if (is.null(labels))
28
+ labels <- as.character(seq_along(x))
29
+ else labels <- as.graphicsAnnot(labels)
30
+ x <- c(0, cumsum(x)/sum(x))
31
+ dx <- diff(x)
32
+ nx <- length(dx)
33
+ plot.new()
34
+ pin <- par("pin")
35
+ xlim <- ylim <- c(-1, 1)
36
+ if (pin[1L] > pin[2L])
37
+ xlim <- (pin[1L]/pin[2L]) * xlim
38
+ else ylim <- (pin[2L]/pin[1L]) * ylim
39
+ dev.hold()
40
+ on.exit(dev.flush())
41
+ plot.window(xlim, ylim, "", asp = 1)
42
+ if (is.null(col))
43
+ col <- if (is.null(density))
44
+ c("white", "lightblue", "mistyrose", "lightcyan",
45
+ "lavender", "cornsilk")
8
- data("USArrests")
46
+ else par("fg")
47
+ if (!is.null(col))
48
+ col <- rep_len(col, nx)
49
+ if (!is.null(border))
50
+ border <- rep_len(border, nx)
51
+ if (!is.null(lty))
52
+ lty <- rep_len(lty, nx)
53
+ angle <- rep(angle, nx)
54
+ if (!is.null(density))
55
+ density <- rep_len(density, nx)
56
+ twopi <- if (clockwise)
57
+ -2 * pi
58
+ else 2 * pi
59
+ t2xy <- function(t) {
60
+ t2p <- twopi * t + init.angle * pi/180
61
+ list(x = radius * cos(t2p), y = radius * sin(t2p))
62
+ }
63
+ for (i in 1L:nx) {
64
+ n <- max(2, floor(edges * dx[i]))
65
+ P <- t2xy(seq.int(x[i], x[i + 1], length.out = n))
66
+ polygon(c(P$x, 0), c(P$y, 0), density = density[i], angle = angle[i],
67
+ border = border[i], col = col[i], lty = lty[i])
68
+ P <- t2xy(mean(x[i + 0:1]))
9
- usa <- unlist(USArrests)[1:12]
69
+ lab <- as.character(labels[i])
70
+ if (!is.na(lab) && nzchar(lab)) {
71
+ lines(c(1, 0.95) * P$x, c(1, 0.95) * P$y)
72
+ text(0.92 * P$x, 0.85 * P$y, labels[i], xpd = TRUE,
73
+ adj = ifelse(P$x > 0, 1, 0), ...)
74
+ }
75
+ }
76
+ title(main = main, ...)
77
+ invisible(NULL)
78
+ }
79
+
80
+ png("graph.png", width = 800, height = 700) # 描画デバイスを開く
81
+
82
+ x <- c(20, 15, 10, 5)
83
+
84
+ # 外側の円
85
+ pie315(x, # ダミー
86
+ radius=0.8, # 半径
87
+ clockwise=T,
10
- cols3 <- brewer.pal(length(usa), "Set3")
88
+ labels=c("A","B","C","D"),
89
+ cex=2,
90
+ col=c("black","yellow","red","blue"))
91
+
92
+ # 重ね描き
11
93
  par(new=TRUE)
12
- pie(usa, radius=0.7, clockwise=TRUE, border="white", labels=head(names(usa),4), col=cols3)
13
94
 
95
+ pie315(x,
96
+ radius=0.6, # 半径
97
+ clockwise=T,
98
+ labels=c("A","B","C","D"),
99
+ cex=2,
100
+ col=c("red","green","blue","gray"))
101
+
102
+ # 重ね描き
14
103
  par(new=TRUE)
104
+
105
+ # 中央の白円
106
+ pie315(1, # ダミー
107
+ radius=0.4, # 半径
108
+ col="white", # 領域の色
15
- pie(5, radius=0.5, col='white', border='white', labels='')
109
+ border="white", # 枠線の色
16
- text(0, 0, labels="Text", cex=par('cex.main'), col=par('col.main'), font=par('font.main'))
110
+ labels="") # ラベル非表示
111
+
112
+ # テキストの挿入
113
+ text(0, 0, # 挿入位置
114
+ labels="pie12",
115
+ cex=3,
116
+ col="red")
117
+
118
+ dev.off()
17
119
  ```
18
120
 
19
- ![double pie charts](018b990b49009c77ca817d065c399aa2.png)
121
+ ![nested pie charts](a2035b2e63710545fd563ae6da3459cb.png)