如何使饼图的标记线大于默认值?

时间:2022-12-03 17:28:48

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:

两种技巧:

  1. You can take the same tact as the original author and code a different magic constant into the code; or

    您可以采用与原作者相同的技巧,并在代码中编写不同的魔术常量;要么

  2. 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:

两种技巧:

  1. You can take the same tact as the original author and code a different magic constant into the code; or

    您可以采用与原作者相同的技巧,并在代码中编写不同的魔术常量;要么

  2. 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))

如何使饼图的标记线大于默认值?