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)
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
(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()
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))
Related Topics
Asymmetric Expansion of Ggplot Axis Limits
Add Data to Ggvis Tooltip That's Contained in the Input Dataset But Not Directly in the Vis
Should I Avoid Programming Packages with Pipe Operators
In Read.Table(): Incomplete Final Line Found by Readtableheader
Number Format, Writing 1E-5 Instead of 0.00001
How to Change Angle of Line in Customized Legend in Ggplot2
Loess Regression on Each Group with Dplyr::Group_By()
Get Monthly Means from Dataframe of Several Years of Daily Temps
Apply() Not Working When Checking Column Class in a Data.Frame
How to Extend Letters Past 26 Characters E.G., Aa, Ab, Ac...
Plotting Ordiellipse Function from Vegan Package Onto Nmds Plot Created in Ggplot2
Finding Non-Numeric Data in a Data Frame or Vector
How to Have Na's Displayed First Using Arrange()
Add Row in Each Group Using Dplyr and Add_Row()