Change lineend for geom_segment()

3,354 views
Skip to first unread message

James Cheshire

unread,
Jan 18, 2012, 7:23:01 AM1/18/12
to ggplot2
Dear Group,

I would like to change the lineend parameter in geom_segment in the
same way that it is possible to do with geom_path() (http://
finzi.psych.upenn.edu/R/library/ggplot2/html/geom_path.html).

In the geom-segment.r file lineend="butt". I have edited it in the
following way (i am only showing the section I have changed).

GeomSegment2 <- proto(Geom, {
draw <- function(., data, scales, coordinates, arrow=NULL, ...) {
if (!coordinates$muncher()) {
return(with(coordinates$transform(data, scales),
segmentsGrob(x, y, xend, yend, default.units="native",
gp = gpar(col=alpha(colour, alpha), lwd=size * .pt,
lty=linetype, lineend = "round"),
arrow = arrow)
))
}
}

And then run:
geom_segment2 <- GeomSegment2$build_accessor()

when I run geom_segment2() the lineends are still "butt" and not
"round". Any ideas as to what I have missed?

Thanks in advance!

James

Dennis Murphy

unread,
Jan 18, 2012, 7:55:06 AM1/18/12
to James Cheshire, ggplot2
Hi:

There's support for this in the upcoming (currently development)
version of ggplot2 (0.9.0), where geom_path() has a new argument
lineend:

lineend Line end style (round, butt, square)

You could wait for the new version (should be soon but no official ETA
yet), or you could install the development version of 0.9.0 as
follows:

library('devtools') # install from CRAN first if necessary
dev_mode()
install_github('ggplot2') # current development version
library('ggplot2')
<your code>

Caution: there are a number of new functions and features, some of
which may break old code. Alternatively, the new code may help you
figure out how to modify the function(s) of interest in 0.8.9.

Dennis

> --
> You received this message because you are subscribed to the ggplot2 mailing list.
> Please provide a reproducible example: http://gist.github.com/270442
>
> To post: email ggp...@googlegroups.com
> To unsubscribe: email ggplot2+u...@googlegroups.com
> More options: http://groups.google.com/group/ggplot2

James Cheshire

unread,
Jan 18, 2012, 8:22:44 AM1/18/12
to ggplot2
Thanks for the reply Dennis. Unfortunately, from what I can make out
looking at the changelog this only applies to geom_path() and I am
interested in geom_segment(). I thought I had got pretty close but
there is obviously a default parameter somewhere that overrides my
changes.

James

James Cheshire

unread,
Jan 21, 2012, 10:48:01 AM1/21/12
to ggp...@googlegroups.com
Here is the code with some sample data:

library(ggplot2)

#load data (100 rows): first two columns are start coordinates, second two are end coordinates, count will determine line size. 


p1<- ggplot(input, aes(x=stlon, y=stlat))

p2<- p1+ geom_segment(aes(xend=elong, yend=elat, size= count))

As you can see in p2 the line ends of each segment are of the butt type but I would like to change them to "round". From what I can make out, this option is available in geom_path() but not geom_segment(). 

Regards and thanks,

James

On 21 January 2012 15:26, Hadley Wickham <had...@rice.edu> wrote:
If you could provide a full reproducible example (i.e. the code you
used with geom_segment2), I'd be more able to take a look quickly.
Please post back to the ggplot2 mailing list.

Hadley

On Wed, Jan 18, 2012 at 5:25 PM, James Cheshire
<james.c...@ucl.ac.uk> wrote:
> Dear Hadley,
>
> Do you have any thoughts on the problem below? I plan to integrate the
> solution into a ggplot2 tutorial I am creating for my research blog.

>
> Thanks in advance!
>
> James
>
> --
> Dr James Cheshire
> Lecturer in Advanced Spatial Analysis
> UCL Centre for Advanced Spatial Analysis
> 1st Floor 90 Tottenham Court Road, London, W1T 4TJ.
> spatialanalysis.co.uk
> +44 (0) 20 3108 3914
>
>
> ---------- Forwarded message ----------
> From: Dennis Murphy <djm...@gmail.com>
> Date: 18 January 2012 22:36
> Subject: Re: Change lineend for geom_segment()
> To: James Cheshire <jache...@gmail.com>
>
>
> Hi:
>
> That's always the rub when dealing with a layered, complex package
> like ggplot2. I was hoping that the new code might be translatable to
> geom_segment(), but was afraid that something would get in the way.
> Alas, I'm not intimate with the inner workings of ggplot2, so I can't
> help much there. Sorry.
>
> Dennis
--
Assistant Professor / Dobelman Family Junior Chair
Department of Statistics / Rice University
http://had.co.nz/



--
spatialanalysis.co.uk

Hadley Wickham

unread,
Jan 30, 2012, 9:38:55 AM1/30/12
to James Cheshire, ggp...@googlegroups.com
Here's a version that works with the current development version:

library(ggplot2)
library(proto)

GeomSegment2 <- proto(ggplot2:::GeomSegment, {
objname <- "geom_segment2"


draw <- function(., data, scales, coordinates, arrow=NULL, ...) {

if (is.linear(coordinates)) {
return(with(coord_transform(coordinates, data, scales),


segmentsGrob(x, y, xend, yend, default.units="native",
gp = gpar(col=alpha(colour, alpha), lwd=size * .pt,
lty=linetype, lineend = "round"),
arrow = arrow)
))
}

}})

geom_segment2 <- function(mapping = NULL, data = NULL, stat =
"identity", position = "identity", arrow = NULL, ...) {
GeomSegment2$new(mapping = mapping, data = data, stat = stat,
position = position, arrow = arrow, ...)
}
df <- data.frame(x = 1, y = 1)
ggplot(df, aes(x , y)) + geom_segment2(aes(xend = x + 1, yend = y +
1), size = 4)
ggplot(df, aes(x , y)) + geom_segment(aes(xend = x + 1, yend = y + 1), size = 4)


I think the main problem with your code was that you were inheriting
from Geom instead of GeomSegment, and so your custom geom was missing
many important functions.

Hadley

James Cheshire

unread,
Feb 2, 2012, 8:32:45 AM2/2/12
to ggplot2
Thanks for you help. This is what I wanted to produce:

http://spatial.ly/yPmMUi

James
> >> > On Wed, Jan 18, 2012 at 5:22 AM, James Cheshire <jachesh...@gmail.com>

Vivek

unread,
Aug 14, 2012, 1:51:13 PM8/14/12
to ggp...@googlegroups.com, James Cheshire, had...@rice.edu
I was trying to use the same argument of lineend = "round" in geom_segment also.

When I run Hadley's code below I get the following error.

Error in get(x, envir = this, inherits = inh)(this, ...) : 
  could not find function "is.linear"

Am I doing something wrong?

thanks,
Vivek
Reply all
Reply to author
Forward
0 new messages