set upper limit in ggplot to include label greater than the maximum value
What about the following solution:
library(ggplot2)
d <- data.frame(x=1:11, y=c(11:17,5:2))
px <- pretty(d$x)
py <- pretty(d$y)
ggplot(d, aes(x,y)) + geom_point() +
scale_x_continuous(breaks=px, limits=range(px)) +
scale_y_continuous(breaks=py, limits=range(px))
How to expand ggplot y axis limits to include maximum value
You can use expand_limits()
to increase the maximum y-axis value. You can also ensure that the maximum y-axis value is rounded up to the next highest value on the scale of the data, e.g., next highest tens value, next highest hundreds value, etc., depending on the whether the highest value in the data is within the tens, hundreds, etc.
For example, the function below finds the base 10 log of the maximum y value and rounds it down. This gives us the base ten scale of the maximum y value (e.g., tens, hundreds, thousands, etc.). It then rounds the maximum y-axis value up to the nearest ten, hundred, etc., that is higher than the maximum y value.
expandy = function(vec, ymin=NULL) {
max.val = max(vec, na.rm=TRUE)
min.log = floor(log10(max.val))
expand_limits(y=c(ymin, ceiling(max.val/10^min.log)*10^min.log))
}
p = mtcars %>% ggplot(aes(x=mpg, y = hp)) +
geom_point()
p + expandy(mtcars$hp)
p + expandy(mtcars$hp, 0)
Or, to make things a bit easier, you could set up the function so that the y-range data is collected directly from the plot:
library(gridExtra)
expandy = function(plot, ymin=0) {
max.y = max(layer_data(plot)$y, na.rm=TRUE)
min.log = floor(log10(max.y))
expand_limits(y=c(ymin, ceiling(max.y/10^min.log)*10^min.log))
}
p = mtcars %>% ggplot(aes(x=mpg, y = hp)) +
geom_point()
grid.arrange(p, p + expandy(p), ncol=2)
p = iris %>% ggplot(aes(x=Sepal.Width, y=Petal.Width)) +
geom_point()
grid.arrange(p, p + expandy(p), ncol=2)
Dynamically use range of pretty breaks to set limits in ggplot
I had this problem crop up again a long time later and found a more rigorous (although not beautiful) approach. Posting in case other people find it helpful.
This requires a custom limits and custom breaks function. The custom breaks function is required because when you call breaks=pretty_breaks()
this is passed the limits of the plot, but these limits are both, already adjusted by the limits=...
and then also expanded (in line with expand = ...
by default multipled by 0.05). So to make sure the pretty breaks line up with the limits based on the original pretty breaks you need to try and back-derive particularly the expansion. This isn't going to be 100% perfect and assumes the default expansion.
I have also included a threshold so the limits don't go below 0 which is useful for me as the numbers I am dealing with a strictly positive but might be close to 0 so a small expansion pushes it below 0. But may not be as useful to others
library(ggplot2)
library(scales)
set.seed(1)
rdat <- data.frame(x = 1:1000,y=runif(1000,min = 0, max = 107))
pretty_lim <- function(x,n=5){
#pretty_lim
r2 <- ifelse(x <0, 0, x)
pr <- pretty(r2,n)
r_out <- range(pr)
r_out
}
pretty_unexpanded <- function(x,n=5){
#expand_limit
if(x[1]<=0){
r2 <- x + c(-x[1],x[1])
}else{
r2 <- x + c((x[2]-x[1])*0.04545455,-(x[2]-x[1])*0.04545455)
}
pout <- pretty(r2,n)
pout
}
#expand near 0
ggplot(rdat, aes(x =x, y = y))+geom_point()+
scale_y_continuous( breaks=pretty_unexpanded,limits = pretty_lim )
#another case no where near 0
rdat2 <- rdat
rdat2$y <- rdat2$y +45
ggplot(rdat2, aes(x =x, y = y))+geom_point()
#Raw Plot
ggplot(rdat2, aes(x =x, y = y))+geom_point()+
scale_y_continuous( breaks=pretty_unexpanded,limits = pretty_lim )
#updated plot with new limits and breaks
Created on 2021-06-07 by the reprex package (v0.3.0)
How to set just one limit for axes in ggplot2 with facets?
Set limits one-sided with NA. Works both in coord_
and scale_
functions
I generally prefer coord_ because it does not remove data. For the example below you would additionally need to remove the margin at 0, e.g. with expand.
library(ggplot2)
carrots <- data.frame(length = rnorm(500000, 10000, 10000))
cukes <- data.frame(length = rnorm(50000, 10000, 20000))
carrots$veg <- 'carrot'
cukes$veg <- 'cuke'
vegLengths <- rbind(carrots, cukes)
ggplot(vegLengths, aes(length, fill = veg)) +
geom_density(alpha = 0.2) +
scale_x_continuous(limits = c(0, NA))
#> Warning: Removed 94542 rows containing non-finite values (stat_density).
ggplot(vegLengths, aes(length, fill = veg)) +
geom_density(alpha = 0.2) +
coord_cartesian(xlim = c(0, NA))
Created on 2020-04-30 by the reprex package (v0.3.0)
remove the margin with expand. Also one sided possible. the right margin is set to the default mult expansion of 0.05 for continous axis.
ggplot(vegLengths, aes(length, fill = veg)) +
geom_density(alpha = 0.2) +
scale_x_continuous(expand = expansion(mult = c(0, 0.05))) +
coord_cartesian(xlim = c(0, NA))
Label minimum and maximum of scale fill gradient legend with text: ggplot2
For scale_fill_gradientn()
you should provide both arguments: breaks=
and labels=
with the same length. With argument limits=
you extend colorbar to minimum and maximum value you need.
ggplot(df, aes(x, y, fill = z)) + geom_raster() +
scale_fill_gradientn(colours=topo.colors(7),na.value = "transparent",
breaks=c(0,0.5,1),labels=c("Minimum",0.5,"Maximum"),
limits=c(0,1))
How to set limits for axes in ggplot2 R plots?
Basically you have two options
scale_x_continuous(limits = c(-5000, 5000))
or
coord_cartesian(xlim = c(-5000, 5000))
Where the first removes all data points outside the given range and the second only adjusts the visible area. In most cases you would not see the difference, but if you fit anything to the data it would probably change the fitted values.
You can also use the shorthand function xlim
(or ylim
), which like the first option removes data points outside of the given range:
+ xlim(-5000, 5000)
For more information check the description of coord_cartesian
.
The RStudio cheatsheet for ggplot2
makes this quite clear visually. Here is a small section of that cheatsheet:
Distributed under CC BY.
Is there a programatic way to pass specific ranges for the y-axis on a ggplot2 plot?
Inspired by teunbrand, I built a function that generates the limits, then checks to ensure that the expansion (including the 5% buffer) does not change the output of pretty
my_lims_expand <- function(x){
prev_pass <-
range(pretty(x))
curr_pass <-
pretty(c(prev_pass[1] - 0.05 * diff(prev_pass)
, prev_pass[2] + 0.05 * diff(prev_pass)))
last_under <-
tail(which(curr_pass < min(x)), 1)
first_over <-
head(which(curr_pass > max(x)), 1)
out <-
range(curr_pass[last_under:first_over])
confirm_out <-
range(pretty(out))
while(!all(out == confirm_out)){
prev_pass <- curr_pass
curr_pass <-
pretty(c(prev_pass[1] - 0.05 * diff(prev_pass)
, prev_pass[2] + 0.05 * diff(prev_pass)))
last_under <-
tail(which(curr_pass < min(x)), 1)
first_over <-
head(which(curr_pass > max(x)), 1)
out <-
range(curr_pass[last_under:first_over])
confirm_out <-
range(pretty(out))
}
return(out)
}
Then, I can use that function for limits
:
ggplot(sample_data,
aes(x = x, y = y)) +
stat_summary(
fun = "mean"
) +
scale_y_continuous(
limits = my_lims_expand
, breaks = pretty
)
to generate the desired plot:
Can I limit ggplot axis range EXACTLY?
As Axeman noted, specifying limits
in scale_y_continuous()
would limit the y-axis. Another alternative is to add coord_cartesian(ylim = c(20, 73))
to your code.
The difference between the two (irrelevant for geom_point
) is that scale_y_continuous(limits = c(...))
would restrict the range of values passed to ggplot for plotting, while coord_cartesian(ylim = c(...))
retricts the visible range after everything has been plotted.
The ggplot2 package cheatsheet over at RStudio summarises this nicely:
As for your issue with some points being cut off at the edge of the panel, you can get around it by converting the plot to a grob, & turning off the panel's clipping:
# plot with restricted range
p <- ggplot(data = mydata, aes(x = x, y = y)) +
geom_point(shape = 21, size = 5, color = "black", fill = "orange", stroke = 1) +
scale_x_continuous(name = 'Number of Contacts') +
scale_y_continuous(name = "Remembered (%)",
expand = c(0, 0),
sec.axis = sec_axis(trans = ~ (.-min(.))*100/(max(.)-min(.)),
name = "Remembered (Index)",
breaks = break2)) +
coord_cartesian(ylim = c(20, 73)) +
theme(plot.margin = margin(t = 10, unit = "pt")) # increase top margin as some points
# are very close to the top edge
# convert to grob
gp <- ggplotGrob(p)
grid::grid.draw(gp) # verify that the points at the edge are cut off
# turn off clipping for panel
gp$layout$clip[gp$layout$name=="panel"] <- "off"
grid::grid.draw(gp) # points at the edge are now visible
Related Topics
How to Install Rhadoop Packages (Rmr, Rhdfs, Rhbase)
Reshape Long Structured Data.Table into a Wide Structure Using Data.Table Functionality
How to Flip Rows and Columns in R
Dplyr Count Number of One Specific Value of Variable
How to Use 'Assign()' or 'Get()' on Specific Named Column of a Dataframe
Remove Empty Factors from Clustered Bargraph in Ggplot2 with Multiple Facets
What Is the Fastest Way to Get a Vector of Sorted Unique Values from a Data.Table
Ggplot: Manual Color Assignment for Single Variable Only
Find the Index of the Column in Data Frame That Contains the String as Value
R Markdown Math Equation Alignment
Plotting a 95% Confidence Interval for a Lm Object
How to Check the Amount of Ram
Sorting of Categorical Variables in Ggplot
Plotting Survival Curves in R with Ggplot2
R:Convert Nested List into a One Level List
Applying Revgeocode to a List of Longitude-Latitude Coordinates