Add Axis Tick-Marks on Top and to the Right to a Ggplot

Add axis tick-marks on top and to the right to a ggplot?

This mirrors the axis tick marks (using gtable functions), and puts the tick marks inside the plot panel.

EDIT 18 April 2016 axis.ticks.margin is deprecated. Use text margins instead.

EDIT 19 Mrch 2015: Better positioning of the tick marks

library(ggplot2) # v2.1.0
library(gtable) # v0.2.0
library(grid)

# Get a plot
p = ggplot(data.frame(x = 1:10, y = 1:10), aes(x,y)) +
geom_point() +
theme_bw() +
theme(panel.grid = element_blank(),
axis.ticks.length=unit(-0.25, "cm"),
axis.text.x = element_text(margin = margin(t = .5, unit = "cm")),
axis.text.y = element_text(margin = margin(r = .5, unit = "cm")))

# Convert the plot to a grob
gt <- ggplotGrob(p)

# Get the position of the panel in the layout
panel <-c(subset(gt$layout, name=="panel", se=t:r))

## For the bottom axis
# Get the row number of the bottom axis in the layout
rn <- which(gt$layout$name == "axis-b")

# Extract the axis (tick marks only)
axis.grob <- gt$grobs[[rn]]
axisb <- axis.grob$children[[2]] # Two children - get the second
axisb # Note: two grobs - tick marks and text

# Get the tick marks
xaxis = axisb$grobs[[1]] # NOTE: tick marks first
xaxis$y = xaxis$y - unit(0.25, "cm") # Position them inside the panel

# Add a new row to gt, and insert the revised xaxis grob into the new row.
gt <- gtable_add_rows(gt, unit(0, "lines"), panel$t-1)
gt <- gtable_add_grob(gt, xaxis, l = panel$l, t = panel$t, r = panel$r, name = "ticks")

## Repeat for the left axis
# Get the row number of the left axis in the layout
panel <-c(subset(gt$layout, name=="panel", se=t:r))
rn <- which(gt$layout$name == "axis-l")

# Extract the axis (tick marks and axis text)
axis.grob <- gt$grobs[[rn]]
axisl <- axis.grob$children[[2]] # Two children - get the second
axisl # Note: two grobs - text and tick marks

# Get the tick marks
yaxis = axisl$grobs[[2]] # NOTE: tick marks second
yaxis$x = yaxis$x - unit(0.25, "cm") # Position them inside the panel

# Add a new column to gt, and insert the revised yaxis grob into the new column.
gt <- gtable_add_cols(gt, unit(0, "lines"), panel$r)
gt <- gtable_add_grob(gt, yaxis, t = panel$t, l = panel$r+1, name = "ticks")

# Turn clipping off
gt$layout[gt$layout$name == "ticks", ]$clip = "off"

# Draw it
grid.draw(gt)

Sample Image

R ggplot2 - Add ticks on top and right sides of all facets

facet_rep_wrap from the lemon package is perfect for this, as it preserves axis lines (& optionally labels) in all facets.

See inline comments below for other tweaks to the code:

library(lemon)

ggplot(df, aes(x=sm, y=lh, colour=exper, shape=month)) +
geom_point(size=2.5, alpha=0.9) +
facet_rep_wrap(~site, nrow = 2) + # instead of facet_wrap
theme_bw(base_size=18) +
ylab(bquote('Latent heat ('*W~m^-2*')')) +
xlab(bquote('Soil water content (%)')) +
scale_x_continuous(sec.axis = dup_axis()) + # add duplicated secondary axis to get
scale_y_continuous(sec.axis = dup_axis()) + # axes on top / right sides
scale_color_manual(values=c("bberry"="tomato2", "medlyn"="dodgerblue"),
labels=c("bberry"="Ball-Berry", "medlyn"="Medlyn")) +
theme(panel.grid.minor=element_blank(),
panel.grid.major=element_blank(),
legend.title=element_blank(),
legend.box="horizontal",
legend.position=c(0.4, 0.6),
legend.spacing = unit(-0.2,"cm"),
strip.placement = "outside", # place facet strips outside axis
axis.ticks.length = unit(-2.75, "pt"), # point axis ticks inwards (2.75pt is
# the default axis tick length here)
axis.text.x.top = element_blank(), # do not show top / right axis labels
axis.text.y.right = element_blank(), # for secondary axis
axis.title.x.top = element_blank(), # as above, don't show axis titles for
axis.title.y.right = element_blank()) # secondary axis either

result

(Note: It's possible to achieve the same result with just ggplot2 & some grob hacking, but that approach is rather more complicated, so I wouldn't go there unless installing new packages is really cumbersome in a computing environment...)

Add axes with ticks and without labels in ggplot

I think you're looking for dup_axis

ggplot(df, aes(x = a, y = b)) + 
geom_point() +
scale_x_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
scale_y_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
theme_classic()

Sample Image

EDIT: I wasn't clear on whether you wanted tick labels, you can add them back by removing the labels = NULL

ggplot: add manually labelled tick marks on top of automatic tick marks

It's unclear exactly what you want this to look like but you could do one of two options. You could either use geom_vline() or geom_segment(). Vline will do a line from the bottom to the top, but it sounds like you may prefer to use segment. Try this:

+ geom_segment(x = min(x), xend = min(x), y = 0, yend = 1)

If you change the yend argument you could make the tick smaller or larger. Drawing one for the max value should be as simple as swapping the min() arguments for max() arguments. Or you could just input the values manually. Alternatively, you could add a vline to go the full height of the panel with:

+ geom_vline(xintercept = min(x))

You can read more about both here. If this doesn't help much, you can provide a proper reprex and maybe a sketch of your desired output we can modify that code to get a bit closer to what you want.

edit:

Writing outside of the plot window is a bit more difficult, but this link may help you. I've tried it on a few and always found that in my cases it was easier to use a different solution. Here's one option:

library(ggplot2)

set.seed(123) # so we have the same toy data

df <- data.frame(x=1:100,y=rnorm(100,10,1))

ggplot(df) +
geom_point(aes(x=x,y=y)) +
geom_segment(x=0, xend=18, y=8.033383, yend=8.033383) + # draw to x axis
geom_segment(x=18, xend=18, y=0, yend=8.033383) + # draw to y axis
annotate("text", 18.2, 8.2, label="(8, 8.03)", size=3) # ordered pair just above it

If you didn't want to draw all the way to the point you could just change the first xend and yend arguments where the x/y start at zero to be come just above the edge of the plot window.

ggplot: Adding a plot outline with the axis ticks

You could duplicate the axes using argument sec.axis = dup_axis() for both scales like so:

library(ggplot2)

ggplot(mtcars, aes(hp, mpg)) +
geom_point() +
scale_x_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
scale_y_continuous(sec.axis = dup_axis(name = NULL, labels = NULL))

Sample Image



Related Topics



Leave a reply



Submit