Duplicating (and modifying) discrete axis in ggplot2 - r

I want to duplicate the left-side Y-axis on a ggplot2 plot onto the right side, and then change the tick labels for a discrete (categorical) axis.
I've read the answer to this question, however as can be seen on the package's repo page, the switch_axis_position() function has been removed from the cowplot package (the author cited (forthcoming?) native functionality in ggplot2).
I've seen the reference page on secondary axes in ggplot2, however all the examples in that document use scale_y_continuous rather than scale_y_discrete. And, indeed, when I try to use the discrete function, I get the error:
Error in discrete_scale(c("y", "ymin", "ymax", "yend"), "position_d", :
unused argument (sec.axis = <environment>)
Is there anyway to do this with ggplot2? Even a completely hacked solution will suffice for me. Thanks in advance. (MREs below)
library(ggplot2)
# Working continuous plot with 2 axes
ggplot(mtcars, aes(cyl, mpg)) +
geom_point() +
scale_y_continuous(sec.axis = sec_axis(~.+10))
# Working discrete plot with 1 axis
ggplot(mtcars, aes(cyl, as.factor(mpg))) +
geom_point()
# Broken discrete plot with 2 axes
ggplot(mtcars, aes(cyl, as.factor(mpg))) +
geom_point() +
scale_y_discrete(sec.axis = sec_axis(~.+10))

Take your discrete factor and represent it numerically. Then you can mirror it and relabel the ticks to be the factor levels instead of numbers.
library(ggplot2)
irislabs1 <- levels(iris$Species)
irislabs2 <- c("foo", "bar", "buzz")
ggplot(iris, aes(Sepal.Length, as.numeric(Species))) +
geom_point() +
scale_y_continuous(breaks = 1:length(irislabs1),
labels = irislabs1,
sec.axis = sec_axis(~.,
breaks = 1:length(irislabs2),
labels = irislabs2))
Then fiddle with the expand = argument in the scale as needed to more closely imitate the default discrete scale.

Related

How do I change labels on y scale of a scatterplot using characters?

An example of my data is:
df <- data.frame(Percent.diff=c(6.3,7.78,12.22,4.81,5.93,8.89),
modal.response=c(1,2,3,1,1,1.5),
Gr=c("R","G","B"),
Sub=c("Plant","Animal","Water"))
I have a scatterplot with a continuous variable (Percent.diff) on the x axis. Although the y axis is numeric (modal.response on a survey question), it relates to categories of responses (ie 0-"The same", 1-"Slightly worse", 2-"Moderately worse",3-"Significantly worse", but there are also responses options in between, eg 1.5). I have made other bar charts with the same data but for this chart specifically I want to make a scatterplot. My only issue is that I want to change the labels of the points on my y axis, so that instead of it simply showing 0-3, I want it to show 0-"The same", 1-"Slightly worse", 2-"Moderately worse",3-"Significantly worse". I have tried making the variable into a factor, but this doesn't work because I think it needs to be a continuous scale and I get the error message "Error: Discrete value supplied to continuous scale".
This is the code I'm using for my plot:
ggplot(df, aes(x=Percent.diff, y=modal.response, color=Sub)) +
geom_point()+
geom_smooth(method=lm, se=FALSE)+
geom_point(aes(shape=Gr, fill=Sub), size=3)+
scale_shape_manual(values=c(3, 8, 21:25))
Thank you
You should probably use scale_y_continuous, making sure breaks and labels have exactly the same length.
If you want to keep 0, then you also have to adjust limits, otherwise it's cropped by default.
This should achieve what you're looking for:
library("ggplot2")
df <- data.frame(Percent.diff=c(6.3,7.78,12.22,4.81,5.93,8.89),
modal.response=c(1,2,3,1,1,1.5),
Gr=c("R","G","B"),
Sub=c("Plant","Animal","Water"))
ggplot(df, aes(x=Percent.diff, y=modal.response, color=Sub)) +
geom_point()+
geom_smooth(method=lm, se=FALSE)+
geom_point(aes(shape=Gr, fill=Sub), size=3)+
scale_shape_manual(values=c(3, 8, 21:25)) +
scale_y_continuous(breaks = c(0:3),
labels=c("0-The same","1-Slightly worse","2-moderately worse","3-significantly worse"),
limits = c(0,3))
#> `geom_smooth()` using formula 'y ~ x'
Created on 2021-08-16 by the reprex package (v2.0.1)

Ggplot2 Boxplot width setting changes x-axis

I have produced a boxplot with a continuous x-axis unsing geom_boxplot() in ggplot2. However, as there are many boxes they appear as skinny lines. Another stackoverflow chain (see here) suggested using the width= argument to make all the boxes the same width. However, when I use this argument it changes the x-axis and some of the boxes just disappear!
For example, take this example dataframe. I apologise for the number of observations this has but I think the quantity has to do with the problem as I couldn't reproduce it with a more simple boxplot:
Lat<- c(50.70228,50.70228,50.70228,51.82067,51.82067,51.82067,52.45893,52.45893,52.45893,52.76478,52.76478,52.76478,52.78354,52.78354,52.78354,53.56102,53.56102,53.56102,53.65364,53.65364,53.65364,53.63130,53.63130,53.63130,54.19035,54.19035,54.19035,54.25751,54.25751,54.25751,54.23526,54.23526,54.23526,54.62469,54.62469,54.62469,54.67831,54.67831,54.67831,54.67900,54.67900,54.67900,54.94908,54.94908,54.94908,55.19456,55.19456,55.19456,54.79198,54.79198,54.79198,55.34981,55.34981,55.34981,55.85655,55.85655,55.85655,56.06078,56.06078,56.06078,55.84553,55.84553,55.84553,56.00197,56.00197,56.00197,56.71842,56.71842,56.71842,57.00116,57.00116,57.00116,57.06942,57.06942,57.06942,57.26815,57.26815,57.26815,57.45532,57.45532,57.45532,57.88596,57.88596,57.88596,51.07711,51.07711,51.07711,51.07801,51.07621,51.11159,51.11159,51.11159,52.02484,52.02484,52.02484,52.02581,52.02581,52.02581,52.02685,52.02685,52.02685,52.05353,52.05353,52.05626,52.05353,52.05353,52.05353,52.05353,52.05353,52.05353,51.93541,51.93541,51.93541,51.93541,51.93541,51.93541,51.93541,51.93541,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.90810,52.90810,52.90810,52.90810,52.90810,52.90810,52.78968,52.78778,52.78968,52.78968,52.78881,52.78883,52.78883,52.78883,52.78970,52.78970,52.79506,52.79506,52.79506,53.77270,53.77276,53.77109,53.77109,53.77276,53.76845,53.76845,53.77109,53.76845,53.77109,53.87020,53.87020,53.87020,53.87103,53.88205,53.88205,53.88205,53.88205,53.87701,53.87701,53.87098,53.87098,53.87098,53.86932,53.86932,53.86932,56.51869,56.51869,56.51869,56.55870,56.55870,56.55870,56.55964,56.55964,56.55964,57.51056,57.49542,57.49542,57.50878,57.50878,57.50878,57.45201,57.45477,57.45192,57.45192,57.45192)
y <- c(33.45407,21.40954,27.73487,20.38318,26.65483,31.68201,23.95467,20.77363,32.94192,22.71228,25.78824,28.39449,35.60615,24.29325,22.95047,25.65343,30.23262,22.05534,37.20565,35.53812,38.20211,39.38034,35.16619,38.82336,29.72370,38.25754,26.51339,39.38283,29.57483,31.80111,24.52967,34.83037,21.75038,35.50868,39.41830,21.96971,22.82504,32.69746,35.10747,27.75669,34.96690,37.61921,37.17226,20.50448,39.26582,22.08668,28.41502,36.69530,23.69404,23.18052,33.27420,23.04157,33.17285,32.00579,21.83845,22.97143,32.27190,21.53771,38.65481,20.14341,33.62718,39.86755,39.77881,30.59810,27.65909,24.11646,34.56981,29.30249,34.99361,32.39553,28.90443,34.88775,22.77049,36.44468,30.64496,35.81501,31.77673,24.19058,39.36298,21.47219,23.02268,31.37647,27.28457,33.14749,23.20842,39.73427,39.81399,35.51515,24.55080,39.41190,29.59987,38.46791,20.94479,37.22109,26.36060,30.91641,39.25975,39.88288,22.59061,30.24439,21.66110,30.36878,28.76901,38.75561,33.80408,31.05842,26.18921,21.30804,35.02966,33.85981,30.84373,31.67341,35.07605,37.93820,31.30481,21.45117,37.13626,25.70964,25.64736,38.58381,31.24448,26.55902,23.90817,33.70300,26.48909,37.73200,32.52413,22.44440,28.19878,32.46415,25.13711,26.66075,28.16254,20.40673,39.89327,30.83327,32.40196,39.81218,39.80391,21.87316,34.95792,33.38958,38.18441,22.03114,35.64410,34.90643,24.23056,36.66581,29.35813,20.86880,30.02044,36.13727,24.65558,39.43175,29.00154,29.78185,22.89196,37.15204,35.88188,28.73920,28.04934,37.50701,30.36306,28.39842,35.20973,26.54260,29.57763,26.03163,26.90440,27.60110,25.80086,39.98019,21.59970,28.83825,32.01711,20.50812,38.43331,32.41898,27.68722,32.59905,24.18150,29.05701,22.38512,32.93342,37.66694,37.65391,34.19613,23.89985,36.90012,20.74244,27.08511,29.21433,35.83771,35.59557,33.74533,27.08854,38.38994)
V3 <-c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2)
df <- as.data.frame(cbind(Lat, y, as.factor(V3)))
head(df)
I plot it on a continuous x-axis as so:
df_plot <- ggplot(df, aes(x=Lat, y=y, group=Lat))+
geom_boxplot(aes(colour=as.factor(V3)))+
theme_classic()
df_plot
Which produces:
As you can see the boxes are represented as skinny lines.
Therefore I tried to use the width= argument as so:
df_plot2 <- ggplot(df, aes(x=Lat, y=y, group=Lat))+
geom_boxplot(aes(colour=as.factor(V3)), width=1)+
theme_classic()
df_plot2
The output is:
The main thing to notice here is that the x-axis range has suddenly changed! Some of the boxes are no longer plotted whilst others seem to be placed at different values of the x-axis.
The range of the x-axis should be:
range(df$Lat)
[1] 50.70228 57.88596
I am completley perplexed as to why the x-axis would change by simply adding the width= argument in geom_boxplot(). I therefore tried to force the limits of the x-axis scale as so:
df_plot3 <- ggplot(df, aes(x=Lat, y=y, group=Lat))+
geom_boxplot(aes(colour=as.factor(V3)), width=1)+
xlim(50,58)+
theme_classic()
df_plot3
ouput:
Please send help!
I think the strange behaviour comes from ggplot trying to automatically dodge your boxplots apart. By setting position = position_dodge(width = 0) the plot seems to be created as expected without changing the placement of boxes along the x-axis. (But gives a warning about overlapping x intervals)
Lat<- c(50.70228,50.70228,50.70228,51.82067,51.82067,51.82067,52.45893,52.45893,52.45893,52.76478,52.76478,52.76478,52.78354,52.78354,52.78354,53.56102,53.56102,53.56102,53.65364,53.65364,53.65364,53.63130,53.63130,53.63130,54.19035,54.19035,54.19035,54.25751,54.25751,54.25751,54.23526,54.23526,54.23526,54.62469,54.62469,54.62469,54.67831,54.67831,54.67831,54.67900,54.67900,54.67900,54.94908,54.94908,54.94908,55.19456,55.19456,55.19456,54.79198,54.79198,54.79198,55.34981,55.34981,55.34981,55.85655,55.85655,55.85655,56.06078,56.06078,56.06078,55.84553,55.84553,55.84553,56.00197,56.00197,56.00197,56.71842,56.71842,56.71842,57.00116,57.00116,57.00116,57.06942,57.06942,57.06942,57.26815,57.26815,57.26815,57.45532,57.45532,57.45532,57.88596,57.88596,57.88596,51.07711,51.07711,51.07711,51.07801,51.07621,51.11159,51.11159,51.11159,52.02484,52.02484,52.02484,52.02581,52.02581,52.02581,52.02685,52.02685,52.02685,52.05353,52.05353,52.05626,52.05353,52.05353,52.05353,52.05353,52.05353,52.05353,51.93541,51.93541,51.93541,51.93541,51.93541,51.93541,51.93541,51.93541,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.92425,52.90810,52.90810,52.90810,52.90810,52.90810,52.90810,52.78968,52.78778,52.78968,52.78968,52.78881,52.78883,52.78883,52.78883,52.78970,52.78970,52.79506,52.79506,52.79506,53.77270,53.77276,53.77109,53.77109,53.77276,53.76845,53.76845,53.77109,53.76845,53.77109,53.87020,53.87020,53.87020,53.87103,53.88205,53.88205,53.88205,53.88205,53.87701,53.87701,53.87098,53.87098,53.87098,53.86932,53.86932,53.86932,56.51869,56.51869,56.51869,56.55870,56.55870,56.55870,56.55964,56.55964,56.55964,57.51056,57.49542,57.49542,57.50878,57.50878,57.50878,57.45201,57.45477,57.45192,57.45192,57.45192)
y <- c(33.45407,21.40954,27.73487,20.38318,26.65483,31.68201,23.95467,20.77363,32.94192,22.71228,25.78824,28.39449,35.60615,24.29325,22.95047,25.65343,30.23262,22.05534,37.20565,35.53812,38.20211,39.38034,35.16619,38.82336,29.72370,38.25754,26.51339,39.38283,29.57483,31.80111,24.52967,34.83037,21.75038,35.50868,39.41830,21.96971,22.82504,32.69746,35.10747,27.75669,34.96690,37.61921,37.17226,20.50448,39.26582,22.08668,28.41502,36.69530,23.69404,23.18052,33.27420,23.04157,33.17285,32.00579,21.83845,22.97143,32.27190,21.53771,38.65481,20.14341,33.62718,39.86755,39.77881,30.59810,27.65909,24.11646,34.56981,29.30249,34.99361,32.39553,28.90443,34.88775,22.77049,36.44468,30.64496,35.81501,31.77673,24.19058,39.36298,21.47219,23.02268,31.37647,27.28457,33.14749,23.20842,39.73427,39.81399,35.51515,24.55080,39.41190,29.59987,38.46791,20.94479,37.22109,26.36060,30.91641,39.25975,39.88288,22.59061,30.24439,21.66110,30.36878,28.76901,38.75561,33.80408,31.05842,26.18921,21.30804,35.02966,33.85981,30.84373,31.67341,35.07605,37.93820,31.30481,21.45117,37.13626,25.70964,25.64736,38.58381,31.24448,26.55902,23.90817,33.70300,26.48909,37.73200,32.52413,22.44440,28.19878,32.46415,25.13711,26.66075,28.16254,20.40673,39.89327,30.83327,32.40196,39.81218,39.80391,21.87316,34.95792,33.38958,38.18441,22.03114,35.64410,34.90643,24.23056,36.66581,29.35813,20.86880,30.02044,36.13727,24.65558,39.43175,29.00154,29.78185,22.89196,37.15204,35.88188,28.73920,28.04934,37.50701,30.36306,28.39842,35.20973,26.54260,29.57763,26.03163,26.90440,27.60110,25.80086,39.98019,21.59970,28.83825,32.01711,20.50812,38.43331,32.41898,27.68722,32.59905,24.18150,29.05701,22.38512,32.93342,37.66694,37.65391,34.19613,23.89985,36.90012,20.74244,27.08511,29.21433,35.83771,35.59557,33.74533,27.08854,38.38994)
V3 <-c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2)
library(ggplot2)
df <- as.data.frame(cbind(Lat, y, as.factor(V3)))
df_plot <- ggplot(df) +
geom_boxplot(aes(colour=as.factor(V3), x=Lat, y=y, group=as.factor(Lat)),
position=position_dodge(width = 0),
width=1) +
theme_classic()

Label right and left side of y axis with different labels using ggplot2 geom_tile function [duplicate]

I want to duplicate the left-side Y-axis on a ggplot2 plot onto the right side, and then change the tick labels for a discrete (categorical) axis.
I've read the answer to this question, however as can be seen on the package's repo page, the switch_axis_position() function has been removed from the cowplot package (the author cited (forthcoming?) native functionality in ggplot2).
I've seen the reference page on secondary axes in ggplot2, however all the examples in that document use scale_y_continuous rather than scale_y_discrete. And, indeed, when I try to use the discrete function, I get the error:
Error in discrete_scale(c("y", "ymin", "ymax", "yend"), "position_d", :
unused argument (sec.axis = <environment>)
Is there anyway to do this with ggplot2? Even a completely hacked solution will suffice for me. Thanks in advance. (MREs below)
library(ggplot2)
# Working continuous plot with 2 axes
ggplot(mtcars, aes(cyl, mpg)) +
geom_point() +
scale_y_continuous(sec.axis = sec_axis(~.+10))
# Working discrete plot with 1 axis
ggplot(mtcars, aes(cyl, as.factor(mpg))) +
geom_point()
# Broken discrete plot with 2 axes
ggplot(mtcars, aes(cyl, as.factor(mpg))) +
geom_point() +
scale_y_discrete(sec.axis = sec_axis(~.+10))
Take your discrete factor and represent it numerically. Then you can mirror it and relabel the ticks to be the factor levels instead of numbers.
library(ggplot2)
irislabs1 <- levels(iris$Species)
irislabs2 <- c("foo", "bar", "buzz")
ggplot(iris, aes(Sepal.Length, as.numeric(Species))) +
geom_point() +
scale_y_continuous(breaks = 1:length(irislabs1),
labels = irislabs1,
sec.axis = sec_axis(~.,
breaks = 1:length(irislabs2),
labels = irislabs2))
Then fiddle with the expand = argument in the scale as needed to more closely imitate the default discrete scale.

changing ggplot legend unit scale

This question is motivated by a previous post illustrating various ways to change how axes scales are plotted in a ggplot figure, from the default exponential notation to the full integer value (when ones axes values are very large). While I am able to convert the axes scales from exponential notation to full values, I am unclear how one would achieve the same goal for the values appearing in the legend.
While I understand that one can manually change the length of the legend scale with "scale_color..." or "scale_fill..." followed by the "limits" argument, this does not appear to be a solution to getting my legend values to show "6000000000" rather than "6e+09" (or "0" rather than "0e+00" for that matter).
The following example should suffice. My hope is someone can point out how to implement the 'scales' package to apply for legend scales rather than axes scales.
Thanks very much.
library(ggplot2)
library(scales)
Data <- data.frame(
pi = c(2,71,828,1828,45904,523536,2874713,52662497,757247093,6999595749),
e = c(3,14,159,2653,58979,311599,7963468,54418516,1590576171, 99),
face = 1:10)
p <- ggplot(data = Data, aes(x=face, y=e, colour = pi))
myplot <- p + geom_point() +
scale_y_continuous(labels = comma) +
scale_color_gradientn(colours = rainbow(2), limits=c(0,7000000000))
myplot
Use the Comma formatter in scale_color_gradientn by setting labels = comma e.g.:
p <- ggplot(data = Data, aes(x=face, y=e, colour = pi))
myplot <- p + geom_point() +
scale_y_continuous(labels = comma) +
scale_color_gradientn(colours = rainbow(2), limits=c(0,7000000000), labels = comma)
myplot

How do you draw a boxplot without specifying x axis?

The base graphics can nicely plot a boxplot using a simple command
data(mtcars)
boxplot(mtcars$mpg)
But qplot requires y axis. How can I achieve with qplot the same like base graphics boxplot and not get this error?
qplot(mtcars$mpg,geom='boxplot')
Error: stat_boxplot requires the following missing aesthetics: y
You have to provide some dummy value to x. theme() elements are used to remove x axis title and ticks.
ggplot(mtcars,aes(x=factor(0),mpg))+geom_boxplot()+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())
Or using qplot() function:
qplot(factor(0),mpg,data=mtcars,geom='boxplot')
you can set the x aesthetics to factor(0) and tweak the appearance by removing unwanted labels:
ggplot(mtcars, aes(x = factor(0), mpg)) +
geom_boxplot() +
scale_x_discrete(breaks = NULL) +
xlab(NULL)
You can also use latticeExtra, to mix boxplot syntax and ggplot2-like theme:
bwplot(~mpg,data =mtcars,
par.settings = ggplot2like(),axis=axis.grid)

Resources