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