回答編集履歴

1

Update

2022/01/03 07:47

投稿

melian
melian

スコア20655

test CHANGED
@@ -1,37 +1,241 @@
1
- 外側からり半径(`radius`)の大きな `pie chart` から描いてい、という手順
1
+ `pie` function のソースコードを見ると以下の部分でラベルを描画していす。`lines()` `tick`(いわゆるヒゲ)、`text()` でラベルを描いているわけですが`1.05` か `1.1` という係数を書き替えます
2
2
 
3
3
  ```r
4
4
 
5
- library(RColorBrewer)
6
-
7
-
8
-
9
- cols <- brewer.pal(length(islands), "Set2")
10
-
11
- pie(islands, radius=0.9, clockwise=TRUE, border="white", labels=head(names(islands),4), col=cols)
12
-
13
-
14
-
15
- data("USArrests")
16
-
17
- usa <- unlist(USArrests)[1:12]
18
-
19
- cols3 <- brewer.pal(length(usa), "Set3")
5
+ if (!is.na(lab) && nzchar(lab)) {
6
+
7
+ lines(c(1, 1.05) * P$x, c(1, 1.05) * P$y)
8
+
9
+ text(1.1 * P$x, 1.1 * P$y, labels[i], xpd = TRUE,
10
+
11
+ adj = ifelse(P$x < 0, 1, 0), ...)
12
+
13
+ }
14
+
15
+ ```
16
+
17
+
18
+
19
+ `R` では monkey patching などということはできないので、`pie()` function のコードをコピペして別名で定義します。そして、`pie chart` の内側にラベルを描くため、先程の係数を調整します。
20
+
21
+ ```r
22
+
23
+ if (!is.na(lab) && nzchar(lab)) {
24
+
25
+ lines(c(1, 0.95) * P$x, c(1, 0.95) * P$y)
26
+
27
+ text(0.92 * P$x, 0.85 * P$y, labels[i], xpd = TRUE,
28
+
29
+ adj = ifelse(P$x > 0, 1, 0), ...)
30
+
31
+ }
32
+
33
+ ```
34
+
35
+
36
+
37
+ 以下、`pie315` という関数名を付けて使います。
38
+
39
+ ```r
40
+
41
+ pie315 <- function (x, labels = names(x), edges = 200, radius = 0.8, clockwise = FALSE,
42
+
43
+ init.angle = if (clockwise) 90 else 0, density = NULL, angle = 45,
44
+
45
+ col = NULL, border = NULL, lty = NULL, main = NULL, ...)
46
+
47
+ {
48
+
49
+ if (!is.numeric(x) || any(is.na(x) | x < 0))
50
+
51
+ stop("'x' values must be positive.")
52
+
53
+ if (is.null(labels))
54
+
55
+ labels <- as.character(seq_along(x))
56
+
57
+ else labels <- as.graphicsAnnot(labels)
58
+
59
+ x <- c(0, cumsum(x)/sum(x))
60
+
61
+ dx <- diff(x)
62
+
63
+ nx <- length(dx)
64
+
65
+ plot.new()
66
+
67
+ pin <- par("pin")
68
+
69
+ xlim <- ylim <- c(-1, 1)
70
+
71
+ if (pin[1L] > pin[2L])
72
+
73
+ xlim <- (pin[1L]/pin[2L]) * xlim
74
+
75
+ else ylim <- (pin[2L]/pin[1L]) * ylim
76
+
77
+ dev.hold()
78
+
79
+ on.exit(dev.flush())
80
+
81
+ plot.window(xlim, ylim, "", asp = 1)
82
+
83
+ if (is.null(col))
84
+
85
+ col <- if (is.null(density))
86
+
87
+ c("white", "lightblue", "mistyrose", "lightcyan",
88
+
89
+ "lavender", "cornsilk")
90
+
91
+ else par("fg")
92
+
93
+ if (!is.null(col))
94
+
95
+ col <- rep_len(col, nx)
96
+
97
+ if (!is.null(border))
98
+
99
+ border <- rep_len(border, nx)
100
+
101
+ if (!is.null(lty))
102
+
103
+ lty <- rep_len(lty, nx)
104
+
105
+ angle <- rep(angle, nx)
106
+
107
+ if (!is.null(density))
108
+
109
+ density <- rep_len(density, nx)
110
+
111
+ twopi <- if (clockwise)
112
+
113
+ -2 * pi
114
+
115
+ else 2 * pi
116
+
117
+ t2xy <- function(t) {
118
+
119
+ t2p <- twopi * t + init.angle * pi/180
120
+
121
+ list(x = radius * cos(t2p), y = radius * sin(t2p))
122
+
123
+ }
124
+
125
+ for (i in 1L:nx) {
126
+
127
+ n <- max(2, floor(edges * dx[i]))
128
+
129
+ P <- t2xy(seq.int(x[i], x[i + 1], length.out = n))
130
+
131
+ polygon(c(P$x, 0), c(P$y, 0), density = density[i], angle = angle[i],
132
+
133
+ border = border[i], col = col[i], lty = lty[i])
134
+
135
+ P <- t2xy(mean(x[i + 0:1]))
136
+
137
+ lab <- as.character(labels[i])
138
+
139
+ if (!is.na(lab) && nzchar(lab)) {
140
+
141
+ lines(c(1, 0.95) * P$x, c(1, 0.95) * P$y)
142
+
143
+ text(0.92 * P$x, 0.85 * P$y, labels[i], xpd = TRUE,
144
+
145
+ adj = ifelse(P$x > 0, 1, 0), ...)
146
+
147
+ }
148
+
149
+ }
150
+
151
+ title(main = main, ...)
152
+
153
+ invisible(NULL)
154
+
155
+ }
156
+
157
+
158
+
159
+ png("graph.png", width = 800, height = 700) # 描画デバイスを開く
160
+
161
+
162
+
163
+ x <- c(20, 15, 10, 5)
164
+
165
+
166
+
167
+ # 外側の円
168
+
169
+ pie315(x, # ダミー
170
+
171
+ radius=0.8, # 半径
172
+
173
+ clockwise=T,
174
+
175
+ labels=c("A","B","C","D"),
176
+
177
+ cex=2,
178
+
179
+ col=c("black","yellow","red","blue"))
180
+
181
+
182
+
183
+ # 重ね描き
20
184
 
21
185
  par(new=TRUE)
22
186
 
187
+
188
+
189
+ pie315(x,
190
+
191
+ radius=0.6, # 半径
192
+
193
+ clockwise=T,
194
+
195
+ labels=c("A","B","C","D"),
196
+
197
+ cex=2,
198
+
23
- pie(usa, radius=0.7, clockwise=TRUE, border="white", labels=head(names(usa),4), col=cols3)
199
+ col=c("red","green","blue","gray"))
200
+
201
+
202
+
24
-
203
+ # 重ね描き
25
-
26
204
 
27
205
  par(new=TRUE)
28
206
 
207
+
208
+
209
+ # 中央の白円
210
+
211
+ pie315(1, # ダミー
212
+
213
+ radius=0.4, # 半径
214
+
215
+ col="white", # 領域の色
216
+
29
- pie(5, radius=0.5, col='white', border='white', labels='')
217
+ border="white", # 枠線の色
30
-
218
+
31
- text(0, 0, labels="Text", cex=par('cex.main'), col=par('col.main'), font=par('font.main'))
219
+ labels="") # ラベル非表示
220
+
221
+
222
+
223
+ # テキストの挿入
224
+
225
+ text(0, 0, # 挿入位置
226
+
227
+ labels="pie12",
228
+
229
+ cex=3,
230
+
231
+ col="red")
232
+
233
+
234
+
235
+ dev.off()
32
236
 
33
237
  ```
34
238
 
35
239
 
36
240
 
37
- ![double pie charts](018b990b49009c77ca817d065c399aa2.png)
241
+ ![nested pie charts](a2035b2e63710545fd563ae6da3459cb.png)