Modify symbols in the legend in a plot mixing geom_point and geom_line

44 views
Skip to first unread message

Vittorio de martino

unread,
Mar 28, 2018, 9:33:08 AM3/28/18
to ggplot2
This is the starting data.frame

mydata <- structure(list(date = structure(c(17197, 17225, 17256, 17286, 
17317, 17347, 17378, 17409, 17439, 17470, 17500, 17531), class = "Date"), 
    trend = c(50.0269807745231, 49.9079174041303, 49.7305604160741, 
    49.741183658644, 49.9452022771566, 50.170406217103, 50.3095823068472, 
    50.4182117454559, 50.5129008767132, 50.6000443177828, 50.732042763593, 
    50.8590001515567), seas = c(52.8086929944926, 50.1397887295428, 
    48.0247110747216, 48.3018488153966, 49.7687103342102, 51.4708124260815, 
    50.0353905837334, 56.7204402229887, 51.1256271469797, 49.5529917864331, 
    51.091476794446, 51.2993119413525), tot = c(54.512, 51.359, 
    46.913, 44.345, 46.287, 53.234, 54.535, 55.002, 50.817, 47.101, 
    52.462, 54.045)), .Names = c("date", "trend", "seas", "tot"
), row.names = c(NA, 12L), class = "data.frame")

Then I executed the the following steps:

library(ggplot2)
library(reshape2)

dt <- melt(mydata,id.vars='date')
dt$variable <- factor(dt$variable, 
                        levels=c('trend','seas','tot'), 
                        labels=c('Trend','Seasonality','Gross')) 

p <- ggplot(dt, aes(x=date,y=value,color=variable)) + 
scale_y_continuous(breaks=seq(40,60,by=2)) + 
xlab(NULL) + ylab("MW") +
theme(legend.position="bottom", legend.title = element_blank()) +
geom_point(data = subset(dt, variable %in% "Gross"), aes(group = variable), shape=3) +
geom_line(data = subset(dt, variable != "Gross"), aes(group = variable)) +
scale_colour_manual("",breaks=c('Gross','Seasonality','Trend'), values=c("Gross"="black","Seasonality"="blue", "Trend"="red")) 

I obtained the enclosed plot.
In the legend the colours of the symbols are correct but not the symbols.
In the legend I would like to have a black '+' for 'Gross', a dotted blue line for 'Seasonality' and a solid red line for 'Trend' ,horizontally lined up. 
How can I get this result?
Ciao
Vittorio
test.png

Crump, Ron

unread,
Mar 28, 2018, 10:12:17 AM3/28/18
to Vittorio de martino, ggplot2
Hi Vittorio,

First off, thanks for the code and data. Made it much easier to
get straight into answering your query.

> library(ggplot2)
> library(reshape2)
>
> dt <- melt(mydata,id.vars='date')
> dt$variable <- factor(dt$variable,
>                         levels=c('trend','seas','tot'),
>                         labels=c('Trend','Seasonality','Gross'))

# I then did...
dt$pt<-ifelse(dt$variable=="Gross",dt$value,NA)
dt$ln<-ifelse(dt$variable!="Gross",dt$value,NA)


> I obtained the enclosed plot.
> In the legend the colours of the symbols are correct but not the symbols.
> In the legend I would like to have a black '+' for 'Gross', a dotted
> blue line for 'Seasonality' and a solid red line for 'Trend'
> ,horizontally lined up.
> How can I get this result?

# How's this?
#
# plot the column pt as y for geom_point (only
# present where variable is "Gross"), and the
# column ln as y for geom_line (absent where
# variable is "Gross", with
# colour, shape and linetype mapped to variable
#
p <- ggplot(dt, aes(x=date,
color=variable,
shape=variable,
linetype=variable)) +
scale_y_continuous(breaks=seq(40,60,by=2)) +
xlab(NULL) +
ylab("MW") +
theme(legend.position="bottom", legend.title = element_blank()) +
geom_point(aes(y=pt)) +
geom_line(aes(y=ln)) +
scale_colour_manual(name="dummy",
breaks=c('Gross','Seasonality','Trend'),
values=c("Gross"="black",
"Seasonality"="blue",
"Trend"="red")) +
scale_shape_manual(name="dummy",
breaks=c('Gross','Seasonality','Trend'),
values=c("Gross"=3,"Seasonality"=NA,"Trend"=NA)) +
scale_linetype_manual(name="dummy",
breaks=c('Gross','Seasonality','Trend'),
values=c("Gross"=0,"Seasonality"=3,"Trend"=1))

Regards,
Ron.

Vittorio de martino

unread,
Mar 28, 2018, 1:14:29 PM3/28/18
to ggplot2
Hi Ron,
thanks again for your valuable help!
I must admit that ggplot2's learning curve is much steeper than I expected.
Ciao 
Vittorio

Crump, Ron

unread,
Mar 29, 2018, 3:48:27 AM3/29/18
to Vittorio de martino, ggplot2
Hi Vittorio,

> thanks again for your valuable help!
> I must admit that ggplot2's learning curve is much steeper than I expected.

It does take a little getting used to.

Once I got the idea of 'long' data and using mapped aesthetics
as much as possible, it gets clearer. Stick at it, I believe
it's worth it.

Thinking about your query a little bit more, it is not necessary to
create the two extra columns (I had that in my head from something
else I'd been doing), the scale_*_manual calls take care of showing
only the desired elements.

Also, if you create the variable factor with the levels in the order
in which you want them later, you can reduce your later code a little:

library(ggplot2)
library(reshape2)
dt <- melt(mydata,id.vars='date')
dt$variable <- factor(dt$variable,
levels=c('tot','seas','trend'),
labels=c('Gross','Seasonality','Trend'))
p <- ggplot(dt, aes(x=date, y=value,
color=variable,
shape=variable,
linetype=variable)) +
scale_y_continuous(breaks=seq(40,60,by=2)) +
xlab(NULL) +
ylab("MW") +
theme(legend.position="bottom", legend.title = element_blank()) +
geom_point() + geom_line() +
scale_colour_manual(values=c("black","blue","red")) +
scale_shape_manual(values=c(3,NA,NA)) +
scale_linetype_manual(values=c(0,3,1))

Regards,
Ron.
Reply all
Reply to author
Forward
0 new messages