[R] Limit the y-axis line with ggplot2 (not the axis itself, but the line used at the left of the graph) [SOLVED]

Paul Murrell paul at stat.auckland.ac.nz
Tue Oct 25 22:58:29 CEST 2016


Hi

Here are some alternatives that involve messing about with the grobs and 
viewports after the plot has been drawn.  The percentage optimality of 
these solutions is up for debate ...

###############################################################################
# Edit the y-axis line after drawing
library("ggplot2"); library("grid")
g <- ggplot()+
   geom_point(aes(x=c(20, 29, 32), y=c(0, 0.4, 1)))+
   scale_y_continuous(breaks=c(0, 0.25, 0.5, 0.75, 1))+
   labs(x="Label for x axis")+
   labs(y="Label for y axis") +
   annotate("text", x = 25 , y=1.2, label="Text 1")+
   annotate("text", x = 22 , y=1.0, label="How to stop the y-axis line 
here !")+
   geom_segment(aes(x=25, xend=25, y=0, yend=1.1), linetype=2)+
   # This part is just to make it more nice
   theme(panel.background = element_rect(fill = 'white'),
         panel.grid.major = element_blank(),
         panel.grid.minor = element_blank(),
         plot.margin = unit(c(0.5, 1, 0.5, 0.5), "cm"),
         axis.text.x=element_text(size=14),
         axis.text.y=element_text(size=14),
         axis.title.x=element_text(size=18),
         axis.title.y=element_text(size=18),
         axis.ticks.length=unit(0.3,"cm"),
         panel.border = element_blank(),
         axis.line.x = element_line(),
         axis.line.y = element_line())
g
# Force creation of all grobs
grid.force()
# List all grobs
grid.ls()
# Get y-axis line y-locations
grid.get("axis.line.y..polyline", grep=TRUE)$y
# Edit y-axis line y-locations (trial-and-error to get 0.81)
grid.edit("axis.line.y..polyline", grep=TRUE, y=unit(c(0, 0.81), "npc"))

###############################################################################
# Insert marker to work off and edit the y-axis line after drawing
library("ggplot2"); library("grid")
g <- ggplot()+
   geom_point(aes(x=c(20, 29, 32), y=c(0, 0.4, 1)))+
   scale_y_continuous(breaks=c(0, 0.25, 0.5, 0.75, 1))+
   labs(x="Label for x axis")+
   labs(y="Label for y axis") +
   annotate("text", x = 25 , y=1.2, label="Text 1")+
   annotate("text", x = 22 , y=1.0, label="How to stop the y-axis line 
here !")+
   geom_segment(aes(x=25, xend=25, y=0, yend=1.1), linetype=2)+
   # This part is just to make it more nice
   theme(panel.background = element_rect(fill = 'white'),
         panel.grid.major = element_blank(),
         panel.grid.minor = element_blank(),
         plot.margin = unit(c(0.5, 1, 0.5, 0.5), "cm"),
         axis.text.x=element_text(size=14),
         axis.text.y=element_text(size=14),
         axis.title.x=element_text(size=18),
         axis.title.y=element_text(size=18),
         axis.ticks.length=unit(0.3,"cm"),
         panel.border = element_blank(),
         axis.line.x = element_line(),
         axis.line.y = element_line()) +
     # marker
     geom_point(aes(x=20, y=1), col="red")
g
# Force creation of all grobs
grid.force()
# List all grobs
grid.ls()
# Navigate to panel viewport
downViewport("panel.6-4-6-4")
# Get marker
marker <- grid.get("geom_point", grep=TRUE, global=TRUE)[[2]]
# Edit y-axis line y-locations (based on marker)
grid.edit("axis.line.y..polyline", grep=TRUE,
           y=convertY(unit(0:1, c("npc", "groby"), list(NULL, marker)), 
"npc"))
# grid.edit("axis.line.y..polyline", grep=TRUE,
#           y=unit(c(0, convertY(grobY(marker, 0), "npc", valueOnly=TRUE)),
#                  "npc"))
# Remove marker
grid.remove(marker$name)

###############################################################################
# Just draw the plot, with margin above, vertical dash line clipped
library("ggplot2"); library("grid")
g <- ggplot()+
   geom_point(aes(x=c(20, 29, 32), y=c(0, 0.4, 1)))+
   scale_y_continuous(breaks=c(0, 0.25, 0.5, 0.75, 1),
                      limits=c(-.05, 1), expand=c(0, 0),
                      oob=function(x, range) x)+
   labs(x="Label for x axis")+
   labs(y="Label for y axis") +
   annotate("text", x = 25 , y=1.2, label="Text 1")+
   annotate("text", x = 22 , y=1.0, label="How to stop the y-axis line 
here !")+
   geom_segment(aes(x=25, xend=25, y=0, yend=1.1), linetype=2)+
   # This part is just to make it more nice
   theme(panel.background = element_rect(fill = 'white'),
         panel.grid.major = element_blank(),
         panel.grid.minor = element_blank(),
         plot.margin = unit(c(3, 1, 0.5, 0.5), "cm"),
         axis.text.x=element_text(size=14),
         axis.text.y=element_text(size=14),
         axis.title.x=element_text(size=18),
         axis.title.y=element_text(size=18),
         axis.ticks.length=unit(0.3,"cm"),
         panel.border = element_blank(),
         axis.line.x = element_line(),
         axis.line.y = element_line())
g
# Force creation of all grobs
grid.force()
# List all grobs
grid.ls()
# Navigate to panel viewport
downViewport("panel.6-4-6-4")
# Get the line segment and label
seg <- grid.get("segments", grep=TRUE)
lab <- grid.get("text", grep=TRUE)
# Push new viewport with clipping off
pushViewport(viewport(clip="off"))
# Draw line segment and text
grid.draw(seg)
grid.draw(lab)
# Clean up
upViewport()

Paul

On 25/10/16 17:33, Marc Girondot wrote:
> After many tries, here is a solution using grob.
> I post here in case it could help someone.
> Note that this solution is not 100% optimal as it uses a trick (limits =
> c(-0.05, 1.02)) to show fully the points.
>
> Marc
>
> library("ggplot2"); require("gtable"); require("grid")
>
> p <- ggplot()+
>   geom_point(aes(x=c(20, 29, 32), y=c(0, 0.4, 1)))+
>   scale_y_continuous(breaks=c(0, 0.25, 0.5, 0.75, 1),
>                      expand = c(0, 0), limits = c(-0.05, 1.02))+
>   xlim(20, 32) +
>   labs(x="Label for x axis")+
>   labs(y="Label for y axis") +
>   geom_segment(aes(x=25, xend=25, y=0, yend=1), linetype=2)+
>   # This part is just to make it more nice
>   theme(panel.background = element_rect(fill = 'white'),
>         panel.grid.major = element_blank(),
>         panel.grid.minor = element_blank(),
>         plot.margin = unit(c(0.5, 1, 0.5, 0.5), "cm"),
>         axis.text.x=element_text(size=14),
>         axis.text.y=element_text(size=14),
>         axis.title.x=element_text(size=18),
>         axis.title.y=element_text(size=18),
>         axis.ticks.length=unit(0.3,"cm"),
>         panel.border = element_blank(),
>         axis.line.x = element_line(),
>         axis.line.y = element_line())
>
>
> # I prepare the legend to be shown at the top
> plegend <- ggplot() +
>   geom_blank() +
>   geom_segment(aes(x=25, xend=25, y=0, yend=0.4), linetype=2) +
>   annotate("text", x = 25 , y=0.5, label="Text 1")+
>   scale_y_continuous(expand=c(0,0), limits = c(0,1)) +
>   scale_x_continuous(limits = c(20, 32)) +
>   theme_minimal() + theme(line=element_blank(),
>                           text=element_blank(),
>                           panel.background=element_blank())
>
> # extract the panel only
> gl <- gtable_filter(ggplotGrob(plegend), "panel")
>
> # And draw both
> g <- ggplotGrob(p)
> g <- gtable_add_rows(x = g, heights = unit(2, "cm"), pos = 0)
> g <- gtable_add_grob(g, gl, t = 2, l=4, b=1, r=4)
> grid.newpage()
> grid.draw(g)
>
>
>
> Le 24/10/2016 à 13:08, Marc Girondot via R-help a écrit :
>> Hello everybody,
>>
>> Using ggplot2 package, is there a way to force to stop the y-axis line
>> at a specified point ? (not using ylim because I want that some text
>> written using annotate() at the top of the graph is still shown).
>>
>> Bellow is a simple example to show what I would like do:
>>
>> Thanks a lot
>>
>> Marc
>>
>>
>>
>>
>>
>> library("ggplot2")
>>
>> g <- ggplot()+
>>   geom_point(aes(x=c(20, 29, 32), y=c(0, 0.4, 1)))+
>>   scale_y_continuous(breaks=c(0, 0.25, 0.5, 0.75, 1))+
>>   labs(x="Label for x axis")+
>>   labs(y="Label for y axis") +
>>   annotate("text", x = 25 , y=1.2, label="Text 1")+
>>   annotate("text", x = 22 , y=1.0, label="How to stop the y-axis line
>> here !")+
>>   geom_segment(aes(x=25, xend=25, y=0, yend=1.1), linetype=2)+
>>   # This part is just to make it more nice
>>   theme(panel.background = element_rect(fill = 'white'),
>>         panel.grid.major = element_blank(),
>>         panel.grid.minor = element_blank(),
>>         plot.margin = unit(c(0.5, 1, 0.5, 0.5), "cm"),
>>         axis.text.x=element_text(size=14),
>>         axis.text.y=element_text(size=14),
>>         axis.title.x=element_text(size=18),
>>         axis.title.y=element_text(size=18),
>>         axis.ticks.length=unit(0.3,"cm"),
>>         panel.border = element_blank(),
>>         axis.line.x = element_line(),
>>         axis.line.y = element_line())
>> g
>>
>> ______________________________________________
>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide
>> http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
>

-- 
Dr Paul Murrell
Department of Statistics
The University of Auckland
Private Bag 92019
Auckland
New Zealand
64 9 3737599 x85392
paul at stat.auckland.ac.nz
http://www.stat.auckland.ac.nz/~paul/



More information about the R-help mailing list