Layered Axes in Ggplot

Layered axes in ggplot?

Two steps to doing this:

  1. Add the group=animal aesthetic to the plot (tell it to group by animal)

  2. Add position="dodge" to your geom_bar layer (tell it the bars should be separate)

Thus:

ggplot(data, aes(x=period, y=value, fill=color, group=animal, color=animal)) +
geom_bar(stat="identity", position="dodge")

This looks like:

Sample Image

One of the issues here is that it doesn't describe which animal is which: there isn't a particularly easy way to fix that. That's why I would probably make this plot through faceting:

ggplot(data, aes(x=animal, y=value, fill=color)) + geom_bar(stat="identity") +
facet_wrap(~ period)

Sample Image

ggplot with 2 y axes on each side and different scales

Sometimes a client wants two y scales. Giving them the "flawed" speech is often pointless. But I do like the ggplot2 insistence on doing things the right way. I am sure that ggplot is in fact educating the average user about proper visualization techniques.

Maybe you can use faceting and scale free to compare the two data series? - e.g. look here: https://github.com/hadley/ggplot2/wiki/Align-two-plots-on-a-page

multiple layer with ggplot in R

This is the max I can produce so far. I have problems to plot density of P.S_tc as a layer because the x axis of a density plot is the variable itself: so in your case Date (desired x axis) competes with P.S_tc:

library(ggplot2)
library(hrbrthemes)

# Value used to transform the data
coeff <- 10000

# constants
CloseColor <- "#69b3a2"
P.S_EWColor <- rgb(0.2, 0.6, 0.9, 1)

p <- ggplot(example, aes(x=Date)) +

geom_line( aes(y=Close), size=1, color=CloseColor) +
geom_line( aes(y=P.S_EW * coeff), size=1, color=P.S_EWColor) +

scale_y_continuous(

# Features of the first axis
name = "Close",

# Add a second axis and specify its features
sec.axis = sec_axis(~.*coeff, name="P.S_EW ($)")
) +

theme_ipsum() +

theme(
axis.title.y = element_text(color = CloseColor, size=13),
axis.title.y.right = element_text(color = P.S_EWColor, size=13)
) +

ggtitle("Close, P.S_EW")

Sample Image

Multi-row x-axis labels in ggplot line chart

New labels are added using annotate(geom = "text",. Turn off clipping of x axis labels with clip = "off" in coord_cartesian.

Use theme to add extra margins (plot.margin) and remove (element_blank()) x axis text (axis.title.x, axis.text.x) and vertical grid lines (panel.grid.x).

library(ggplot2)

ggplot(data = df, aes(x = interaction(year, quarter, lex.order = TRUE),
y = sales, group = 1)) +
geom_line(colour = "blue") +
annotate(geom = "text", x = seq_len(nrow(df)), y = 34, label = df$quarter, size = 4) +
annotate(geom = "text", x = 2.5 + 4 * (0:4), y = 32, label = unique(df$year), size = 6) +
coord_cartesian(ylim = c(35, 65), expand = FALSE, clip = "off") +
theme_bw() +
theme(plot.margin = unit(c(1, 1, 4, 1), "lines"),
axis.title.x = element_blank(),
axis.text.x = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())

Sample Image


See also the nice answer by @eipi10 here: Axis labels on two lines with nested x variables (year below months)

double labels on x and y axis in ggplot

I think you can do it with scale_*_continuous. You can use it to do the transformation and then you can change the labels manually (using the labels argument).

library(ggplot2)

df.data <- data.frame(x=c(1, 2, 3, 4, 5),
y=c(1, 10, 100, 1000, 10000))

labels.y <- paste(round(log10(df.data$y),1), df.data$y, sep='\n')
labels.x <- paste(round(log10(df.data$x),1), df.data$x, sep='\n')

ggplot(df.data) +
geom_line(aes(x=x, y=y)) +
scale_y_continuous(breaks = df.data$y,
trans = 'log10',
labels=labels.y) +
scale_x_continuous(breaks = df.data$x,
trans = 'log10',
labels=labels.x) +
xlab('log(x)\nx') + ylab('log(y)\ny') +
theme(axis.title.y = element_text(angle=0),
axis.title.x = element_text(angle=0,hjust=1))

Sample Image

Add layer without it affecting training of scales

You could substitute an annotation_custom (which doesn't train the scales) in place of a geom_hline. In your case it would be:

g <- g + annotation_custom(
grid::linesGrob(y = unit(c(0, 0), "npc")), ymin = 250, ymax = 250)

So now:

g

Sample Image

but

g %+% mtcars[mtcars$cyl < 8,]

Sample Image



Related Topics



Leave a reply



Submit