I'm trying to plot multiple lines as a part of a single "class" in ggplot2. I can plot something like the following:
But my issue is that I want to show n1, n2, and n3 as a single class (grey thin lines for each with a single name in the legend).
My problem is that if I create a new factor in the data frame in order to group them, I end up drawing the addition connection from the end of n1 (upper right) to the beginning of n2 (lower left) which adds a diagonal across my graph:
That's closer to what I want, but has the additional diagonal line. If it matters, I'm computing these using ROCR then extracting the x and y points from the resultant performance
object in order to produce these lines.
Here's one way, but I don't think you'll like it very much:
d1 <- data.frame(x = 1:10,
y = rep(1:2,each = 5),
grp = factor(rep(letters[1:2],each = 5),levels = letters[1:3]))
d1 <- rbind(d1,data.frame(x = 1:2,y = c(NA,NA),grp = c('c','c')))
d2 <- data.frame(x = 1:15,
y = rep(3:5,each = 5),
grp = rep(1:3,each = 5))
ggplot() +
geom_line(data = d1,aes(x = x,y = y,group = grp,colour = grp)) +
geom_line(data = d2,aes(x = x,y = y,group = grp),colour = "blue")
Note that your solution won't work well with other kinds of data. It just happens that each of the three lines you want to merge into the same category in the legend begin and end in basically the same spot. If that weren't the case, you'd end up with unwanted connector lines.
The above method will work more generally, but as you can see isn't less awkward. If anything it's more inconvenient.
This kind of issue has come up many times, and it could be that I'm forgetting a simpler solution. But in general, try to keep in mind that in exchange for ggplot2 saving you from having to construct every legend manually, you (frequently, but not always) are sacrificing some flexibility, compared to base graphics.
I had rbind
'd the items from the ROCR performance
object into a data.frame directly when trying to plot this graph. I realize that I could cut the trip from the top-right to the lower-left by reversing the order of the middle class of data. i.e.
n1 <- getPerformance(test1)
n2 <- getPerformance(test2)
n3 <- getPerformance(test3)
would create three data frames looking like
type x y
1 n1 0 0.000000000
2 n1 0 0.003448276
3 n1 0 0.006896552
4 n1 0 0.010344828
5 n1 0 0.013793103
6 n1 0 0.017241379
...
26565 n1 0.9999619 1
26566 n1 1.0000000 1
The problem here is that when I rbind n1 to n2, I'd be connecting n1's point (1,1) to n2's point (0,0) -- creating the diagonal line.
In my case, one (sloppy) solution was to merely reverse the order of every other line so that there was no diagonal line.
n2_rev <- n2[nrow(n2):1,]
ns <- rbind(n1,n2_rev,n3)
So now the line goes back-and-forth instead of starting and ending at the same position consistently, creating the following graph:
Nonetheless, I assume there's a more universal way to handle this. Is there a good way to add a line to a ggplot2 graph such as the lines()
function for base R?