问题描述
我有一个使用stat.funciton的基本情节:
I have a basic plot using stat.funciton:
x<-c(-5,5)
fun.1 <- function(x) x^2 + x
p<-ggplot(data.frame(x=x),aes(x)) +stat_function(fun = fun.1,geom="line")
print(p)
有什么方法可以改变以y值为条件的绘图的线型吗?换句话说,如何更改该图,以使曲线上位于y = 10处的值以虚线而不是实线绘制?请注意,我可以为x值绘制单独的曲线,并分段定义函数,但是我正在寻找一个更简单的解决方案.
Is there any way to change the linetype of the plot conditional on the y-value? In other words, how can I change this plot so that values on the curve that lie above, say, y=10, are plotted as dotted instead of solid line? Note I get that I could make separate curves for the x-values, and define the function piecewise, but I'm looking for a simpler solution.
followibng代码(逐段定义的x)似乎也不起作用:
The followibng code (piecewise-defined x) doesnt seem to work either:
x1<-c(-5,4)
fun.1 <- function(x1) x1^2 + x1
x2<-c(4,5)
fun.2 <- function(x2) x2^2 + x2
p1<-ggplot(data.frame(x=x1),aes(x1)) +stat_function(fun = fun.1,geom="line")
p1<-p1+ggplot(data=data.frame(x2),aes(x2))+stat_function(fun = fun.2,geom="line",lty=2)
print(p1)
>Error: Don't know how to add o to a plot
但是,第二个绘图单独完成时可以工作:
However the second plot works when done separately:
x2<-c(4,5)
fun.2 <- function(x2) x2^2 + x2
p2<-ggplot(data=data.frame(x2),aes(x2))+stat_function(fun = fun.2,geom="line",lty=2)
print(p2)
请帮助?
推荐答案
您需要为曲线10上方/下方的每个线段创建单独的组.
You need to create a separate group for each segment of the curve that is above/below 10.
ggplot(data.frame(x=x),aes(x)) +
stat_function(fun = fun.1,geom="line", n=400,
aes(group=factor(c(0,cumsum(diff(..y.. >= 10) != 0))),
linetype=factor(c(0,cumsum(diff(..y.. >= 10) != 0))))) +
scale_linetype_manual(values=c(2,1,2)) +
guides(linetype=FALSE)
下面是有关如何创建组的更多详细信息.首先,我们从一个简单的y
向量开始进行说明:
Below is more detail on how the groups are created. First we start with a simple y
vector for illustration:
> y = c(7:13,12:7)
> y
[1] 7 8 9 10 11 12 13 12 11 10 9 8 7
现在让我们找到曲线在10之上或之下的位置:
Now let's find where the curve is above or below 10:
> y >= 10
[1] FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE
数学函数将逻辑TRUE
和FALSE
的数值分别设置为1和0,因此我们现在可以找到曲线与y==10
相交的特定值:
Mathematical functions treat logical TRUE
and FALSE
as having numeric values of, respectively, 1 and 0, so we can now find the specific values at which the curve crosses y==10
:
> diff(y >=10)
[1] 0 0 1 0 0 0 0 0 0 -1 0 0
我们希望每次曲线穿过y==10
时都增加一个新组:
We want to increment to a new group each time the curve crosses y==10
:
> diff(y >=10) != 0
[1] FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
> cumsum(diff(y >=10) != 0)
[1] 0 0 1 1 1 1 1 1 1 2 2 2
因此,现在我们有三个不同的组.但是diff
返回的向量比原始向量短一个.因此,我们将0
添加到分组向量的开头,以使其与数据向量的长度相同.
So now we have three different groups. But diff
returns a vector that is one shorter than the original vector. So we add 0
onto the beginning of the grouping vector so that it will be the same length as the data vectors.
> c(0, cumsum(diff(y >=10) != 0))
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2
最后,我们将其转换为因子,否则线型会给我们将连续变量映射到linetype
的错误:
Finally, we convert it to a factor, otherwise linetype will give us an error for mapping a continuous variable to linetype
:
> factor(c(0, cumsum(diff(y >=10) != 0)))
[1] 0 0 0 1 1 1 1 1 1 1 2 2 2
Levels: 0 1 2
此外,..y..
是ggplot内部计算出的y
值的向量以绘制函数,因此这就是为什么我们在ggplot中使用..y..
的原因.
Also, ..y..
is the vector of y
values internally calculated by ggplot to plot your function, so that's why we use ..y..
inside ggplot.
这篇关于ggplot2中的条件图线型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!