I would like to make line longer and different in angle of printed sliced labelled line.
我想在打印的切片标记线的角度上制作更长和不同的线。
Note: I am not talking about clockwise = TRUE
.
注意:我不是说顺时针= TRUE。
code:
码:
pie.sales <- c(0.12, 0.3, 0.26, 0.16, 0.04, 0.12)
names(pie.sales) <- c("Blueberry", "Cherry","Apple", "Boston Cream", "Other", "Vanilla Cream")
pie(pie.sales)
1 个解决方案
#1
1
Unfortunately, the length of the line is hard-coded in the function. If you look at the function (just type pie
), look towards the bottom:
不幸的是,线的长度在函数中是硬编码的。如果你看一下这个函数(只需输入pie),请查看底部:
function (x, labels = names(x), edges = 200, radius = 0.8, clockwise = FALSE,
init.angle = if (clockwise) 90 else 0, density = NULL, angle = 45,
col = NULL, border = NULL, lty = NULL, main = NULL, ...)
{
if (!is.numeric(x) || any(is.na(x) | x < 0))
stop("'x' values must be positive.")
## ...snip... ##
if (!is.na(lab) && nzchar(lab)) {
lines(c(1, 1.05) * P$x, c(1, 1.05) * P$y)
text(1.1 * P$x, 1.1 * P$y, labels[i], xpd = TRUE,
adj = ifelse(P$x < 0, 1, 0), ...)
}
}
title(main = main, ...)
invisible(NULL)
}
You can see the hard-coded 1.05 (twice) for line length, and 1.1 (twice) for text placement. If you take this function, copy it, and redefine it as a new function (perhaps in a .R
script file), you can fix this for your own use.
您可以看到硬编码1.05(两次)的行长度,1.1(两次)用于文本放置。如果您使用此功能,复制它,并将其重新定义为新功能(可能在.R脚本文件中),您可以修复此功能供您自己使用。
Two techniques:
两种技巧:
-
You can take the same tact as the original author and code a different magic constant into the code; or
您可以采用与原作者相同的技巧,并在代码中编写不同的魔术常量;要么
-
You can add a couple of options that allow you to control the length of the line and (optionally) the gap between the line and the text.
您可以添加几个选项,以允许您控制线的长度和(可选)线和文本之间的间隙。
I've done #2, below. I changed the definition of arguments (within function(...)
) as well as those two lines towards the bottom, nothing more:
我已经完成了#2,下面。我更改了参数的定义(在函数(...)中)以及这两行到底部,仅此而已:
mypie <- function (x, labels = names(x), edges = 200, radius = 0.8, clockwise = FALSE,
init.angle = if (clockwise) 90 else 0, density = NULL, angle = 45,
col = NULL, border = NULL, lty = NULL, main = NULL, len = 0.05, lengap = 0.1, ...)
{
if (!is.numeric(x) || any(is.na(x) | x < 0))
stop("'x' values must be positive.")
## ...snip... ##
if (!is.na(lab) && nzchar(lab)) {
lines(c(1, 1 + len) * P$x, c(1, 1 + len) * P$y)
text((1 + len + lengap) * P$x, (1 + len + lengap) * P$y, labels[i], xpd = TRUE,
adj = ifelse(P$x < 0, 1, 0), ...)
}
}
title(main = main, ...)
invisible(NULL)
}
With this, you can change your call to something like mypie(pie.sales, radius = 0.5, len = 0.6, lengap = 0.3)
.
有了这个,您可以将您的调用更改为mypie(pie.sales,radius = 0.5,len = 0.6,lengap = 0.3)。
Now, the next question is how to get the labels aligned better on the ticks, but that's a different question (and will cost you twice as much as you paid for this answer).
现在,接下来的问题是如何让标签在刻度线上更好地对齐,但这是一个不同的问题(并且将花费你为此答案付出的两倍)。
EDIT
编辑
It is possible to have different lengths for each label, perhaps to mitigate overlapping labels. There are perhaps better ways to do it, but a little brute-force and elbow-grease is good for the programmer's soul every now and then ...
每个标签可以有不同的长度,可能是为了减轻重叠标签。也许有更好的方法可以做到这一点,但是一点点蛮力和肘部油脂对于程序员的灵魂不时有好处......
Before the for(i in 1L:nx)
line at the end of the function, add:
在函数末尾的for(i in 1L:nx)行之前,添加:
list(x = radius * cos(t2p), y = radius * sin(t2p))
}
if (length(len) == 1) len <- rep(len, length(x)) # new
if (length(lengap) == 1) lengap <- rep(lengap, length(x)) # new
for (i in 1L:nx) {
n <- max(2, floor(edges * dx[i]))
(First two and last two lines there were supplied for context only.)
(前两行和后两行仅供上下文使用。)
Now change the lines
and text
lines accordingly (to add per-slice subsetting):
现在相应地更改行和文本行(添加每个切片子集):
if (!is.na(lab) && nzchar(lab)) {
lines(c(1, 1 + len[i]) * P$x, c(1, 1 + len[i]) * P$y)
text((1 + len[i] + lengap[i]) * P$x, (1 + len[i] + lengap[i]) * P$y, labels[i], xpd = TRUE,
adj = ifelse(P$x < 0, 1, 0), ...)
}
Now set len
differently for each slice of the pie, same order:
现在为饼图的每个切片设置不同的len,顺序相同:
mypie(pie.sales, len = c(0.05, 0.05, 0.05, 0.25, 0.1, 0.05))
#1
1
Unfortunately, the length of the line is hard-coded in the function. If you look at the function (just type pie
), look towards the bottom:
不幸的是,线的长度在函数中是硬编码的。如果你看一下这个函数(只需输入pie),请查看底部:
function (x, labels = names(x), edges = 200, radius = 0.8, clockwise = FALSE,
init.angle = if (clockwise) 90 else 0, density = NULL, angle = 45,
col = NULL, border = NULL, lty = NULL, main = NULL, ...)
{
if (!is.numeric(x) || any(is.na(x) | x < 0))
stop("'x' values must be positive.")
## ...snip... ##
if (!is.na(lab) && nzchar(lab)) {
lines(c(1, 1.05) * P$x, c(1, 1.05) * P$y)
text(1.1 * P$x, 1.1 * P$y, labels[i], xpd = TRUE,
adj = ifelse(P$x < 0, 1, 0), ...)
}
}
title(main = main, ...)
invisible(NULL)
}
You can see the hard-coded 1.05 (twice) for line length, and 1.1 (twice) for text placement. If you take this function, copy it, and redefine it as a new function (perhaps in a .R
script file), you can fix this for your own use.
您可以看到硬编码1.05(两次)的行长度,1.1(两次)用于文本放置。如果您使用此功能,复制它,并将其重新定义为新功能(可能在.R脚本文件中),您可以修复此功能供您自己使用。
Two techniques:
两种技巧:
-
You can take the same tact as the original author and code a different magic constant into the code; or
您可以采用与原作者相同的技巧,并在代码中编写不同的魔术常量;要么
-
You can add a couple of options that allow you to control the length of the line and (optionally) the gap between the line and the text.
您可以添加几个选项,以允许您控制线的长度和(可选)线和文本之间的间隙。
I've done #2, below. I changed the definition of arguments (within function(...)
) as well as those two lines towards the bottom, nothing more:
我已经完成了#2,下面。我更改了参数的定义(在函数(...)中)以及这两行到底部,仅此而已:
mypie <- function (x, labels = names(x), edges = 200, radius = 0.8, clockwise = FALSE,
init.angle = if (clockwise) 90 else 0, density = NULL, angle = 45,
col = NULL, border = NULL, lty = NULL, main = NULL, len = 0.05, lengap = 0.1, ...)
{
if (!is.numeric(x) || any(is.na(x) | x < 0))
stop("'x' values must be positive.")
## ...snip... ##
if (!is.na(lab) && nzchar(lab)) {
lines(c(1, 1 + len) * P$x, c(1, 1 + len) * P$y)
text((1 + len + lengap) * P$x, (1 + len + lengap) * P$y, labels[i], xpd = TRUE,
adj = ifelse(P$x < 0, 1, 0), ...)
}
}
title(main = main, ...)
invisible(NULL)
}
With this, you can change your call to something like mypie(pie.sales, radius = 0.5, len = 0.6, lengap = 0.3)
.
有了这个,您可以将您的调用更改为mypie(pie.sales,radius = 0.5,len = 0.6,lengap = 0.3)。
Now, the next question is how to get the labels aligned better on the ticks, but that's a different question (and will cost you twice as much as you paid for this answer).
现在,接下来的问题是如何让标签在刻度线上更好地对齐,但这是一个不同的问题(并且将花费你为此答案付出的两倍)。
EDIT
编辑
It is possible to have different lengths for each label, perhaps to mitigate overlapping labels. There are perhaps better ways to do it, but a little brute-force and elbow-grease is good for the programmer's soul every now and then ...
每个标签可以有不同的长度,可能是为了减轻重叠标签。也许有更好的方法可以做到这一点,但是一点点蛮力和肘部油脂对于程序员的灵魂不时有好处......
Before the for(i in 1L:nx)
line at the end of the function, add:
在函数末尾的for(i in 1L:nx)行之前,添加:
list(x = radius * cos(t2p), y = radius * sin(t2p))
}
if (length(len) == 1) len <- rep(len, length(x)) # new
if (length(lengap) == 1) lengap <- rep(lengap, length(x)) # new
for (i in 1L:nx) {
n <- max(2, floor(edges * dx[i]))
(First two and last two lines there were supplied for context only.)
(前两行和后两行仅供上下文使用。)
Now change the lines
and text
lines accordingly (to add per-slice subsetting):
现在相应地更改行和文本行(添加每个切片子集):
if (!is.na(lab) && nzchar(lab)) {
lines(c(1, 1 + len[i]) * P$x, c(1, 1 + len[i]) * P$y)
text((1 + len[i] + lengap[i]) * P$x, (1 + len[i] + lengap[i]) * P$y, labels[i], xpd = TRUE,
adj = ifelse(P$x < 0, 1, 0), ...)
}
Now set len
differently for each slice of the pie, same order:
现在为饼图的每个切片设置不同的len,顺序相同:
mypie(pie.sales, len = c(0.05, 0.05, 0.05, 0.25, 0.1, 0.05))