1

I currently have the below plot in R. I was wondering if it was possible to end the curves once they hit zero. For example, once z hits zero is it possible to remove the line and points on the plot after 10^4?

enter image description here

ydot.dplyr <- ydot.n0 %>% select(variables, variable, value) %>%
                group_by(variables) %>%
                do(as.data.frame(spline(x= .[["variable"]], y= .[["value"]], n = nrow(.)*10)))


ggplot(ydot.n0, aes(variable, value)) +
   geom_point(aes(colour = factor(variables))) +
   geom_line(data = ydot.dplyr, aes(x = x, y = y, colour = factor(variables)))

   variables variable        value
1          1     10^2   0.00000000
2          x     10^2   0.00000000
3          y     10^2  -2.98409634
4          z     10^2  -7.92656901
5         xx     10^2   0.78848436
6         xy     10^2   0.00000000
7         xz     10^2   0.00000000
8         yy     10^2   0.00000000
9         yz     10^2   0.00000000
10         1   10^2.5   0.00000000
11         x   10^2.5  -2.28064813
12         y   10^2.5   4.00588146
13         z   10^2.5 -10.72326346
14        xx   10^2.5   0.61528135
15        xy   10^2.5           NA
16        xz   10^2.5           NA
17        yy   10^2.5           NA
18        yz   10^2.5           NA
19         1     10^3   0.00000000
20         x     10^3  -0.01460549
21         y     10^3   5.26084263
22         z     10^3  -2.95040569
23        xx     10^3   0.00000000
24        xy     10^3   0.00000000
25        xz     10^3   0.00000000
26        yy     10^3   0.63388822
27        yz     10^3  -0.59157518
28         1   10^3.5   0.00000000
29         x   10^3.5  28.00000000
30         y   10^3.5  -1.00000000
31         z   10^3.5   0.00000000
32        xx   10^3.5   0.00000000
33        xy   10^3.5   0.00000000
34        xz   10^3.5  -1.00000000
35        yy   10^3.5   0.00000000
36        yz   10^3.5   0.00000000
37         1     10^4   0.00000000
38         x     10^4  28.00000000
39         y     10^4  -1.00000000
40         z     10^4   0.00000000
41        xx     10^4   0.00000000
42        xy     10^4   0.00000000
43        xz     10^4  -1.00000000
44        yy     10^4   0.00000000
45        yz     10^4   0.00000000
46         1   10^4.5   0.00000000
47         x   10^4.5  28.00000000
48         y   10^4.5  -1.00000000
49         z   10^4.5   0.00000000
50        xx   10^4.5   0.00000000
51        xy   10^4.5   0.00000000
52        xz   10^4.5  -1.00000000
53        yy   10^4.5   0.00000000
54        yz   10^4.5   0.00000000
55         1     10^5   0.00000000
56         x     10^5  28.00000000
57         y     10^5  -1.00000000
58         z     10^5   0.00000000
59        xx     10^5   0.00000000
60        xy     10^5   0.00000000
61        xz     10^5  -1.00000000
62        yy     10^5   0.00000000
63        yz     10^5   0.00000000

I've edited and added data. By "hitting zero" I mean that the data points above at zero should no longer appear on the graph. Further, the data should only appear once it becomes nonzero.

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
AW27
  • 481
  • 3
  • 15
  • welcome to SO. This question lacks a reproducible example (your sample data). Also, please clarify what you mean with 'once it hits zero'. How close to zero? This could be more challenging than you think - ever heard of floating numbers? I guess you want to remove all values after the first occurrence of zero? Something like `ydot.n0 %>% group_by(variable) %>% slice(1:which.min(value == 0))` may help – tjebo Mar 19 '20 at 10:49
  • Sorry about that, I added some data from using: ydot.n0 <- melt(iterative.ydot.df, id.vars="variables") ydot.n0[ydot.n0$values == 0] <- NA The curved graph was later created using Dplyr – AW27 Mar 19 '20 at 11:26
  • Please take a look at [How to make a great R reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). It is difficult to assist you if we cannot reproduce your results. – hendrikvanb Mar 19 '20 at 11:59

2 Answers2

1

Still not quite clear when you want to cut off the lines. Here is one suggestion.

library(tidyverse)

# fill NAs with 0, and convert x to numeric. This is for the spline calculation
ydot_filled <- ydot.n0 %>% mutate(value = zoo::na.fill(value, 0), x= as.numeric(as.factor(variable))) 

# I've changed your do call to lapply after splitting the data frame first, then binding back to create a new data frame. 
y_line <- lapply(split(ydot_filled, ydot.n0$variables), 
       function(u) as.data.frame(spline(x= u[["x"]], y= u[["value"]], n = nrow(u)*10))) %>%
  bind_rows(.id = 'variable') %>% 
  mutate(y = round(y,2)) %>% # helps avoid floating numbers
  group_by(variable) %>% 
  mutate(cum0 = cumsum(y == 0 )) %>% # this is to get the first 0
  filter(cum0 < 1) # remove all rows after first zero. Note some have value == 0 from the start

ggplot() +
  geom_point(data = ydot_filled, aes(x= x, y = value, colour = variables))  +
  geom_line(data = y_line, aes(x = x, y = y, colour = variable))

As you can see - it does not cut of some lines that 'cross' zero, because their splines never equal zero. this is what I meant with your problem is probably more challenging than you think. You'd need to also remove lines when the values change their symbol etc.

Created on 2020-03-19 by the reprex package (v0.3.0)

Data

# devtools::install_github("alistaire47/read.so")
ydot.n0 <- read.so::read.so("variables variable        value
1          1     10^2   0.00000000
2          x     10^2   0.00000000
3          y     10^2  -2.98409634
4          z     10^2  -7.92656901
5         xx     10^2   0.78848436
6         xy     10^2   0.00000000
7         xz     10^2   0.00000000
8         yy     10^2   0.00000000
9         yz     10^2   0.00000000
10         1   10^2.5   0.00000000
11         x   10^2.5  -2.28064813
12         y   10^2.5   4.00588146
13         z   10^2.5 -10.72326346
14        xx   10^2.5   0.61528135
15        xy   10^2.5           NA
16        xz   10^2.5           NA
17        yy   10^2.5           NA
18        yz   10^2.5           NA
19         1     10^3   0.00000000
20         x     10^3  -0.01460549
21         y     10^3   5.26084263
22         z     10^3  -2.95040569
23        xx     10^3   0.00000000
24        xy     10^3   0.00000000
25        xz     10^3   0.00000000
26        yy     10^3   0.63388822
27        yz     10^3  -0.59157518
28         1   10^3.5   0.00000000
29         x   10^3.5  28.00000000
30         y   10^3.5  -1.00000000
31         z   10^3.5   0.00000000
32        xx   10^3.5   0.00000000
33        xy   10^3.5   0.00000000
34        xz   10^3.5  -1.00000000
35        yy   10^3.5   0.00000000
36        yz   10^3.5   0.00000000
37         1     10^4   0.00000000
38         x     10^4  28.00000000
39         y     10^4  -1.00000000
40         z     10^4   0.00000000
41        xx     10^4   0.00000000
42        xy     10^4   0.00000000
43        xz     10^4  -1.00000000
44        yy     10^4   0.00000000
45        yz     10^4   0.00000000
46         1   10^4.5   0.00000000
47         x   10^4.5  28.00000000
48         y   10^4.5  -1.00000000
49         z   10^4.5   0.00000000
50        xx   10^4.5   0.00000000
51        xy   10^4.5   0.00000000
52        xz   10^4.5  -1.00000000
53        yy   10^4.5   0.00000000
54        yz   10^4.5   0.00000000
55         1     10^5   0.00000000
56         x     10^5  28.00000000
57         y     10^5  -1.00000000
58         z     10^5   0.00000000
59        xx     10^5   0.00000000
60        xy     10^5   0.00000000
61        xz     10^5  -1.00000000
62        yy     10^5   0.00000000
63        yz     10^5   0.00000000")
tjebo
  • 21,977
  • 7
  • 58
  • 94
0

I cannot quite use your dataset easily, but from what I see, you want to only plot those points that are > (or equal to) 0, right? In this case, it might have a pretty simple solution for you. I'll use a dummy dataset for the +/- y values:

df1 <- data.frame(x=seq(4, 10, by=0.1), y=cos(seq(4,10,by=0.1)), id='cos')
df2 <- data.frame(x=seq(4, 10, by=0.1), y=sin(seq(4,10,by=0.1)), id='sin')
df <- rbind(df1, df2)

Plotting these you get:

ggplot(df, aes(x,y)) + geom_line(aes(color=id))

enter image description here

If you want to eliminate any points below y=0, you just plot a subset of the data:

ggplot(df, aes(x,y)) + geom_line(data=subset(df,y>=0), aes(color=id))

enter image description here

Limits of x and y axes can be changed with xlim() and ylim() calls to your plot.

Community
  • 1
  • 1
chemdork123
  • 12,369
  • 2
  • 16
  • 32