Formatting Ggplot2 Axis Labels with Commas (And K? Mm) If I Already Have a Y-Scale

Formatting ggplot2 axis labels with commas (and K? MM?) if I already have a y-scale

For the comma formatting, you need to include the scales library for label=comma. The "error" you discussed is actually just a warning, because you used both ylim and then scale_y_continuous. The second call overrides the first. You can instead set the limits and specify comma-separated labels in a single call to scale_y_continuous:

library(scales)

ggplot(df, aes(x = Date, y = Cost))+
geom_line(lwd = 0.5) +
geom_line(aes(y = Cost_7), col = 'red', linetype = 3, lwd = 1) +
geom_line(aes(y = Cost_30), col = 'blue', linetype = 5, lwd = 0.75) +
xlim(c(left, right)) +
xlab("") +
scale_y_continuous(label=comma, limits=c(min(df$Cost[df$Date > left]),
max(df$Cost[df$Date > left])))

Another option would be to melt your data to long format before plotting, which reduces the amount of code needed and streamlines aesthetic mappings:

library(reshape2)

ggplot(melt(df, id.var="Date"),
aes(x = Date, y = value, color=variable, linetype=variable))+
geom_line() +
xlim(c(left, right)) +
labs(x="", y="Cost") +
scale_y_continuous(label=comma, limits=c(min(df$Cost[df$Date > left]),
max(df$Cost[df$Date > left])))

Either way, to put the y values in terms of thousands or millions you could divide the y values by 1,000 or 1,000,000. I've used dollar_format() below, but I think you'll also need to divide by the appropriate power of ten if you use unit_format (per @joran's suggestion). For example:

div=1000

ggplot(melt(df, id.var="Date"),
aes(x = Date, y = value/div, color=variable, linetype=variable))+
geom_line() +
xlim(c(left, right)) +
labs(x="", y="Cost (Thousands)") +
scale_y_continuous(label=dollar_format(),
limits=c(min(df$Cost[df$Date > left]),
max(df$Cost[df$Date > left]))/div)

Use scale_color_manual and scale_linetype_manual to set custom colors and linetypes, if desired.

Sample Image

in R use `$` and `K` as a y-axis labels for thousands of dollars

You can use scales::dollar_format to achieve what you're going for:

ggplot(df, aes(Date, Values)) + 
geom_line() +
scale_y_continuous(labels = scales::dollar_format(scale = .001, suffix = "K"))

In ggplot/facet_wrap(), how to marke axis Y have different format

One option would be the ggh4x package which via facetted_pos_scales allows to set the scales individually for each facet:

library(ggplot2)
library(ggh4x)

ggplot(plot_data, aes(x=mseq,y=amount))+geom_line()+geom_point()+
facet_wrap(.~type,scales='free_y') +
facetted_pos_scales(
y = list(
type == "price" ~ scale_y_continuous(labels = scales::comma_format()),
type == "x_to_price" ~ scale_y_continuous(labels = scales::percent_format())
)
)

Sample Image

Format ggplot2 axis labels such that only numbers 9999 have commas

We can use an anonymous function within scale_x_continuous:

library(scales)
library(ggplot2)

# generate dummy data
x <- 9998:10004
df <- data.frame(x, y = seq_along(x))

ggplot(df, aes(x = x, y = y))+
geom_point()+
scale_x_continuous(labels = function(l) ifelse(l <= 9999, l, comma(l)))

Sample Image

How do I correct the scale and order of the y axis in R on a barplot

The question you were pointing to contains a very good idea, to use geom_rect instead. You could do something like the following (comments in code)

library(tidyverse)

# just some fake data, similar to yours
foo <- data.frame(id = "id", layer = letters[1:6], depth = c(5,10,12,15,20,25))

foo2 <-
foo %>%
# using lag to create ymin, which is needed for geom_rect
# transforming id into integers so i can add / subtract some x for xmin/xmax
mutate( ymin = lag(depth, default = 0),
id_int = as.integer(factor(id)))

# I am turning off the legend and labelling the layers directly instead
# using geom_text
# this creates a "wrong" y axis title which I'm changing with labs(y = ... )
# the continuous x axis needs to be turned into a fake discrete axis by
# semi-manually setting the breaks and labels
ggplot(foo2) +
geom_rect(aes(xmin = id_int - .5, xmax = id_int +.5,
ymin = ymin, ymax = depth,
fill = layer), show.legend = FALSE) +
geom_text(aes(x = id_int, y = (depth + ymin)/2, label = layer)) +
scale_x_continuous(breaks = foo2$id_int, labels = foo2$id) +
labs(y = "depth")

Sample Image

Created on 2021-10-19 by the reprex package (v2.0.1)

Log axis labels in ggplot2: full number without comma?

There may be a better way to do this, but I just looked at code of comma() (by typing the function name by itself) and wrote a new plain() function that doesn't use the big.mark="," argument:

plain <- function(x,...) {
format(x, ..., scientific = FALSE, trim = TRUE)
}
ggplot(df, aes(x=x, y=y))+
geom_point()+scale_x_log10(labels=plain)+scale_y_log10(labels=plain)

How to use axis range and labels from original data in ggtern?

The solution you have provided is along the right path, however, all arguments to the limit_term(...) function (or aliases) are expected to be in the range [0,1] which corresponds to [0,100%]. Values can be supplied outside of this range, however, this will serve to resolve limits which will contain values greater than 100% and less than 0%.

In summary, use of the following:

tern_limits(T=12, L=10, R=4)

is actually asking for the ternary limits to be bound by 1200%, 1000% and 400% maxima respectively, which is exactly as your attempted result has been rendered.

Anyway, here are some examples of the limits_tern and zoom functionality.

library(ggtern)

n = 100
df = data.frame(id=1:n,
x=runif(n),
y=runif(n),
z=runif(n))
base = ggtern(df,aes(x,y,z,color=id)) + geom_point(size=3)
base

#Top Corner
base + limit_tern(1.0,0.5,0.5)

#Left Corner
base + limit_tern(0.5,1.0,0.5)

#Right Corner
base + limit_tern(0.5,0.5,1.0)

#Center Zoom Convenience Function
base + theme_zoom_center(0.4) # Zoom In
base + theme_zoom_center(0.6) # Zoom In
base + theme_zoom_center(0.8) # Zoom In
base + theme_zoom_center(1.0) ##Default as per no zoom
base + theme_zoom_center(1.2) # Zoom Out
base + theme_zoom_center(1.4) # Zoom Out
base + theme_zoom_center(1.6) # Zoom Out
base + theme_zoom_center(1.8) # Zoom Out
base + theme_zoom_center(2.0) # Zoom Out

#Left Zoom Convenience Function
# (try theme_zoom_R and theme_zoom_T for Right and Top respectively)
base + theme_zoom_L(0.4) # Zoom In
base + theme_zoom_L(0.6) # Zoom In
base + theme_zoom_L(0.8) # Zoom In
base + theme_zoom_L(1.0) ##Default as per no zoom
base + theme_zoom_L(1.2) # Zoom Out
base + theme_zoom_L(1.4) # Zoom Out
base + theme_zoom_L(1.6) # Zoom Out
base + theme_zoom_L(1.8) # Zoom Out
base + theme_zoom_L(2.0) # Zoom Out

Note: that these are all convenience functions to make zooming easier than controlling the limits independently (which is valid) via scale_X_continuous(...) [X = T,L,R]. Unlike a purely cartesian coordinate system where x and y are independent, in the ternary system, the limits must make sense so that the three apex points satisfy conditions of the simplex.

If you have to control each axis independently, here below is an example where each limits is defined, the axis breaks and the axis labels, for the T, L and R axis respectively. If the limits are nonsensical in terms of the simplex conditions, an error will be thrown.

ggtern() + 
scale_T_continuous(limits=c(0.5,1.0),
breaks=seq(0,1,by=0.1),
labels=LETTERS[1:11]) +
scale_L_continuous(limits=c(0.0,0.5),
breaks=seq(0,1,by=0.1),
labels=LETTERS[1:11]) +
scale_R_continuous(limits=c(0.0,0.5),
breaks=seq(0,1,by=0.1),
labels=LETTERS[1:11])

X-Y Axis Formatting in R

Unless your plot is enormous (much bigger than your screen), the number of labels you're asking for will be unreadable, because they'll overlay each other. Following the spirit of what you're asking for (y-ticks every 5000, commas in y labels, more x labels that make sense):

# enlarge left margin to accommodate transposed labels
par(mar = c(5.1, 6.1, 2.1, 2.1))

# a sequence for tick marks
y_seq <- seq((min(sales) %/% 5000) * 5000,
(max(sales) %/% 5000 + 1) * 5000,
by = 5000)

# a sequence for labels
y_labs <- prettyNum(y_seq, big.mark = ',')
y_labs[seq(1, length(y_labs), 2)] <- NA

plot(date, sales, type="s", ylab=NA, xaxt = 'n', yaxt = 'n')

# `axis.Date` makes sequencing and formatting easy; adapt as you like
axis.Date(1, date, at = seq.Date(min(date), max(date), by = 'year'), format = '%Y')
axis(2, at = y_seq, labels = y_labs, las = 2)

# add y label in a readable location
title(ylab = 'Sales', mgp = c(4.5, 1, 0))

which produces
plot with fixed axis labels

If you want more labels, the approach is pretty customizable from here.

One last point: While you can always fight base R graphics until they do what you want, sometimes the fight isn't worth it when ggplot2 has much better defaults.

Just two lines:

library(ggplot2)
qplot(date, sales, geom = 'step')

makes

ggplot version



Related Topics



Leave a reply



Submit