Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot error using linetype and group aesthetics

Tags:

r

ggplot2

I'm trying to make plot based on the following data

dt <- data.frame(ValuationDate = seq.Date(as.Date("2014-1-1"), 
                 as.Date("2014-7-1"), by = "month"), 
                 Adjuster = factor(c("Bob","Bob","Sue","Sue","Sue","Sue","Bob")),
                 Paid = c(1,2,3,4,5,6,7), Incurred = c(3,5,9,9,10,8,7))
dt <- melt(dt, measure.vars = c("Paid", "Incurred"), 
           variable.name = "Value", value.name = "Amount")
dt
   ValuationDate Adjuster    Value Amount
1     2014-01-01      Bob     Paid      1
2     2014-02-01      Bob     Paid      2
3     2014-03-01      Sue     Paid      3
4     2014-04-01      Sue     Paid      4
5     2014-05-01      Sue     Paid      5
6     2014-06-01      Sue     Paid      6
7     2014-07-01      Bob     Paid      7
8     2014-01-01      Bob Incurred      3
9     2014-02-01      Bob Incurred      5
10    2014-03-01      Sue Incurred      9
11    2014-04-01      Sue Incurred      9
12    2014-05-01      Sue Incurred     10
13    2014-06-01      Sue Incurred      8
14    2014-07-01      Bob Incurred      7

For each ValuationDate, there is a "Paid" amount and an "Incurred" amount which I'd like to plot over time, associating each time period with an Adjuster. When I try doing

#with grouping variable and linetype (error)
ggplot(data = dt) + geom_step(aes(x = ValuationDate, 
                                  y = Amount, group = Value, 
                                  color = Adjuster, linetype = Value))

I get "Error: geom_path: If you are using dotted or dashed lines, colour, size and linetype must be constant over the line"

However the following two plots work

#with grouping variable, without linetype
ggplot(data = dt) + geom_step(aes(x = ValuationDate, y = Amount,
                                  group = Value, color = Adjuster))

enter image description here

#with linetype, without grouping variable
ggplot(data = dt) + geom_step(aes(x = ValuationDate, y = Amount,
                                  color = Adjuster, linetype = Value))

enter image description here

What gives?

like image 928
Ben Avatar asked Oct 23 '25 04:10

Ben


2 Answers

Let's take a look at the piece of code that generates the error:

# Work out whether we should use lines or segments
attr <- ddply(munched, .(group), function(df) {
  data.frame(
    solid = identical(unique(df$linetype), 1),
    constant = nrow(unique(df[, c("alpha", "colour","size", "linetype")])) == 1
  )
})
solid_lines <- all(attr$solid)
constant <- all(attr$constant)
if (!solid_lines && !constant) {
  stop("geom_path: If you are using dotted or dashed lines",
    ", colour, size and linetype must be constant over the line",
    call.=FALSE)
}

So if there are at least two different linetypes, all other aes should be unique. I cannot say why exactly this limitation is present, probably it caused some rendering related issues.

You can make the lines distinguishable by other means, e.g. by varying size or alpha instead of linetype. Another possibility would be adding

geom_point(aes(x = ValuationDate, y = Amount, group = Value, shape = Value), size = 3)

enter image description here

like image 129
tonytonov Avatar answered Oct 25 '25 18:10

tonytonov


You will have to use separate geom_step calls for each unique Value x Adjuster segment.

gg <- ggplot()
for (i in 1:6) gg <- gg + 
  geom_step(data=subset(your_dt, Segment==i), 
            aes(x=ValuationDate, y=Amount, color=Adjuster, linetype=Value, group=i))

Produces (on call to gg): enter image description here

To rig it to get continuous stepped lines (i.e. the output you want), you have to insert some dummy/duplicate rows. I did that manually, but depending on how often you are doing this you'll probably want a function to insert these rows. Segment can be easily calculated by comparing Adjuster and Value to the prior row.

your_dt:

   ValuationDate Adjuster    Value Amount DummyRow Segment
1       1/1/2014      Bob     Paid      1       no       1
2       2/1/2014      Bob     Paid      2       no       1
3       3/1/2014      Bob     Paid      2      yes       1
4       3/1/2014      Sue     Paid      2      yes       2
5       3/1/2014      Sue     Paid      3       no       2
6       4/1/2014      Sue     Paid      4       no       2
7       5/1/2014      Sue     Paid      5       no       2
8       6/1/2014      Sue     Paid      6       no       2
9       7/1/2014      Sue     Paid      6      yes       2
10      7/1/2014      Bob     Paid      6      yes       3
11      7/1/2014      Bob     Paid      7       no       3
12      1/1/2014      Bob Incurred      3       no       4
13      2/1/2014      Bob Incurred      5       no       4
14      3/1/2014      Bob Incurred      5      yes       4
15      3/1/2014      Sue Incurred      5      yes       5
16      3/1/2014      Sue Incurred      9       no       5
17      4/1/2014      Sue Incurred      9       no       5
18      5/1/2014      Sue Incurred     10       no       5
19      6/1/2014      Sue Incurred      8       no       5
20      7/1/2014      Sue Incurred      8      yes       5
21      7/1/2014      Bob Incurred      8      yes       6
22      7/1/2014      Bob Incurred      7       no       6
like image 24
arvi1000 Avatar answered Oct 25 '25 19:10

arvi1000



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!