My current plot:
My desired plot (nevermind the variables s)
Specifically: explanatory variables on the bottom with an x-axis, response variables on the right, relative frequency and the y-axis on the left. I'll attach my R code below.
mosaictable <- matrix (c (3, 9, 22, 21), byrow = T, ncol = 2)
rownames (mosaictable) = c ("White", "Blue ")
colnames (mosaictable) = c ("Captured", "Not Captured")
mosaicplot ((mosaictable), sub = "Pigeon Color", ylab = "Relative frequency",
col = c ("firebrick", "goldenrod1"), font = 2, main = "Mosaic Plot of Pigeon Color and Their Capture Rate"
)
axis (1)
axis (4)
This particular flavor of mosaic display where you have a "dependent" variable on the y-axis and want to add corresponding annotation, is sometimes also called a "spine plot". R implements this in the spineplot() function. Also plot(y ~ x) internally calls spineplot() when both y and x are categorical.
In your case, spineplot() does almost everything you want automatically provided that you supply it with a nicely formatted "table" object:
tab <- as.table(matrix(c(3, 22, 9, 21), ncol = 2))
dimnames(tab) <- list(
"Pigeon Color" = c("White", "Blue"),
"Relative Frequency" = c("Captured", "Not Captured")
)
tab
## Relative Frequency
## Pigeon Color Captured Not Captured
## White 3 9
## Blue 22 21
And then you get:
spineplot(tab)
Personally, I would leave it at that. But if it is really important to switch the axis labels from left to right and vice versa, then you can do so by first suppressing axes = FALSE and then adding them manually afterwards. The coordinates for that need to be obtained from the marginal distribution of the first variable and the conditional distribution of the second variable given the first, respectively
x <- prop.table(margin.table(tab, 1))
y <- prop.table(tab, 1)[2, ]
spineplot(tab, col = c("firebrick", "goldenrod1"), axes = FALSE)
axis(1, at = c(0, x[1]) + x/2, labels = rownames(tab), tick = FALSE)
axis(2)
axis(4, at = c(0, y[1]) + y/2, labels = colnames(tab), tick = FALSE)
Related
I am doing quarterly analysis, for which I want to plot a graph. To maintain continuity on x axis I have turned quarters into factors. But then when I am using plot function and trying to color it red, the col argument is not working.
An example:
quarterly_analysis <- data.frame(Quarter = as.factor(c(2020.1,2020.2,2020.3,2020.4,2021.1,2021.2,2021.3,2021.4)),
AvgDefault = as.numeric(c(0.24,0.27,0.17,0.35,0.32,0.42,0.38,0.40)))
plot(quarterly_analysis, col="red")
But I am getting the graph in black color as shown below:
Converting it to a factor is not ideal to plot unless you have multiple values for each factor - it tries to plot a box plot-style plot. For example, with 10 observations in the same factor, the col = "red" color shows up as the fill:
set.seed(123)
fact_example <- data.frame(factvar = as.factor(rep(LETTERS[1:3], 10)),
numvar = runif(30))
plot(fact_example$factvar, fact_example$numvar,
col = "red")
With only one observation for each factor, this is not ideal because it is just showing you the line that the box plot would make.
You could use border = "red:
plot(quarterly_analysis$Quarter,
quarterly_analysis$AvgDefault, border="red")
Or if you want more flexibility, you can plot it numerically and do a little tweaking for more control (i.e., can change the pch, or make it a line graph):
# make numeric x values to plot
x_vals <- as.numeric(substr(quarterly_analysis$Quarter,1,4)) + rep(seq(0, 1, length.out = 4))
par(mfrow=c(1,3))
plot(x_vals,
quarterly_analysis$AvgDefault, col="red",
pch = 7, main = "Square Symbol", axes = FALSE)
axis(1, at = x_vals,
labels = quarterly_analysis$Quarter)
axis(2)
plot(x_vals,
quarterly_analysis$AvgDefault, col="red",
type = "l", main = "Line graph", axes = FALSE)
axis(1, at = x_vals,
labels = quarterly_analysis$Quarter)
axis(2)
plot(x_vals,
quarterly_analysis$AvgDefault, col="red",
type = "b", pch = 7, main = "Both", axes = FALSE)
axis(1, at = x_vals,
labels = quarterly_analysis$Quarter)
axis(2)
Data
set.seed(123)
quarterly_analysis <- data.frame(Quarter = as.factor(paste0(2019:2022,
rep(c(".1", ".2", ".3", ".4"),
each = 4))),
AvgDefault = runif(16))
quarterly_analysis <- quarterly_analysis[order(quarterly_analysis$Quarter),]
I am planning to reproduce the attached figure, but I have no clue how to do so:
Let´s say I would be using the CO2 example dataset, and I would like to plot the relative change of the Uptake according to the Treatment. Instead of having the three variables in the example figure, I would like to show the different Plants grouped for each day/Type.
So far, I managed only to get this bit of code, but this is far away from what it should look like.
aov1 <- aov(CO2$uptake~CO2$Type+CO2$Treatment+CO2$Plant)
plot(TukeyHSD(aov1, conf.level=.95))
Axes should be switched, and I would like to add statistical significant changes indicated with letters or stars.
You can do this by building it in base R - this should get you started. See comments in code for each step, and I suggest running it line by line to see what's being done to customize for your specifications:
Set up data
# Run model
aov1 <- aov(CO2$uptake ~ CO2$Type + CO2$Treatment + CO2$Plant)
# Organize plot data
aov_plotdata <- data.frame(coef(aov1), confint(aov1))[-1,] # remove intercept
aov_plotdata$coef_label <- LETTERS[1:nrow(aov_plotdata)] # Example labels
Build plot
#set up plot elements
xvals <- 1:nrow(aov_plotdata)
yvals <- range(aov_plotdata[,2:3])
# Build plot
plot(x = range(xvals), y = yvals, type = 'n', axes = FALSE, xlab = '', ylab = '') # set up blank plot
points(x = xvals, y = aov_plotdata[,1], pch = 19, col = xvals) # add in point estimate
segments(x0 = xvals, y0 = aov_plotdata[,2], y1 = aov_plotdata[,3], lty = 1, col = xvals) # add in 95% CI lines
axis(1, at = xvals, label = aov_plotdata$coef_label) # add in x axis
axis(2, at = seq(floor(min(yvals)), ceiling(max(yvals)), 10)) # add in y axis
segments(x0=min(xvals), x1 = max(xvals), y0=0, lty = 2) #add in midline
legend(x = max(xvals)-2, y = max(yvals), aov_plotdata$coef_label, bty = "n", # add in legend
pch = 19,col = xvals, ncol = 2)
My current plot:
My desired plot (nevermind the variables s)
Specifically: explanatory variables on the bottom with an x-axis, response variables on the right, relative frequency and the y-axis on the left. I'll attach my R code below.
mosaictable <- matrix (c (3, 9, 22, 21), byrow = T, ncol = 2)
rownames (mosaictable) = c ("White", "Blue ")
colnames (mosaictable) = c ("Captured", "Not Captured")
mosaicplot ((mosaictable), sub = "Pigeon Color", ylab = "Relative frequency",
col = c ("firebrick", "goldenrod1"), font = 2, main = "Mosaic Plot of Pigeon Color and Their Capture Rate"
)
axis (1)
axis (4)
This particular flavor of mosaic display where you have a "dependent" variable on the y-axis and want to add corresponding annotation, is sometimes also called a "spine plot". R implements this in the spineplot() function. Also plot(y ~ x) internally calls spineplot() when both y and x are categorical.
In your case, spineplot() does almost everything you want automatically provided that you supply it with a nicely formatted "table" object:
tab <- as.table(matrix(c(3, 22, 9, 21), ncol = 2))
dimnames(tab) <- list(
"Pigeon Color" = c("White", "Blue"),
"Relative Frequency" = c("Captured", "Not Captured")
)
tab
## Relative Frequency
## Pigeon Color Captured Not Captured
## White 3 9
## Blue 22 21
And then you get:
spineplot(tab)
Personally, I would leave it at that. But if it is really important to switch the axis labels from left to right and vice versa, then you can do so by first suppressing axes = FALSE and then adding them manually afterwards. The coordinates for that need to be obtained from the marginal distribution of the first variable and the conditional distribution of the second variable given the first, respectively
x <- prop.table(margin.table(tab, 1))
y <- prop.table(tab, 1)[2, ]
spineplot(tab, col = c("firebrick", "goldenrod1"), axes = FALSE)
axis(1, at = c(0, x[1]) + x/2, labels = rownames(tab), tick = FALSE)
axis(2)
axis(4, at = c(0, y[1]) + y/2, labels = colnames(tab), tick = FALSE)
I'd like to make a histogram of my variable "sex" with the values 1 = male and 2 = female. My code works properly, but I'd like to have only the values 1 and 2 on the x-axis (at the moment R prints all values between 0 and 1 in steps which makes less sense in the case of sex).
hist(g1_sex,
main = "Häufigkeitsverteilung Geschlecht",
sub = "1 = männlich, 2 = weiblich",
xlab = "Geschlecht",
ylab ="Häufigkeit",
ylim = c(0,120),
col = "lightblue",
labels = TRUE,
breaks=2)
I already tried to do it with
breaks = seq (1,2,1)
but this doesn't look nice too.
I would be very thankful for every hint of you!
Best wishes!
I think you really want barplot. See examples:
set.seed(0); x <- rbinom(500, 1, 0.3) ## generate toy 0-1 data
y <- table(x) ## make contingency table
names(y) <- c("male", "female")
ylim = c(0, 1.2 * max(y)) ## set plotting range
z <- barplot(y, space = 0, col = 5, main = "statistics", ylim = ylim)
text(z, y + 20, y, cex = 2, col = 5) ## add count number above each bar
I have also give solutions to add number above each bar, by setting extra space on the top using ylim, and use text to put texts.
Note that barplot also accepts main, etc, so you can add other annotations if you want.
So I am trying to add some graphs to my notes. I have created a simple interest function that will plot several simple interest functions using different rates and I would like to add a legend that would simple say...
"i =: 0%, x%, y%, z%" on one single line, where each 0,x,y,z is in the different color of the representative function using that interest rate.
I looked into the paste() function and attempted to make it one string but I am not sure exactly how to loop it into the int_seq and pull out each individual index and make it a different color then put it into a single string.
# indexs to be used
t = 0:50
int_seq = seq(0.025,0.10,by=0.025) # intere rate sequence
colors = c("red","blue","green","orange") #colors of interest rate seq
index = 1:length(int_seq)
# AV Simple Interest (all good)
avSimple = function(i,t){
av = (1 + (i * t))
return(av)}
# Plot range for y-axis (all good)
yrange = c(avSimple(min(int_seq),min(t)) * 0.95,
avSimple(max(int_seq),max(t)) * 1.05)
# Plots Simple Interest with different interest rates (all good)
plot(t,avSimple(0,t), type="l", main = "AV Simple Interest", xlab = "Time",
ylab = "AV", ylim = yrange)
# loops through the int_seq and plots line based on interest rate
# and specified color (all good)
for (i in index)
lines(t,avSimple(int_seq[i],t), col = colors[i])
# Adds legend to plot for different interest rates
# !!This is where I need the help, not sure best way to approach!!
legend(0,avSimple(0.075,50), c("i =: 0%", for (i in index) int_seq[i]),
col = colors)
Not sure what kind of legend you want. Since you say in one line, you might want to add horiz = TRUE, but here are some other options:
You can pass full vectors to legend so there is no need for a loop in this case. Just create a vector of labels but also use a vector of colors corresponding to each label (which you have already done).
# indexs to be used
t = 0:50
int_seq = seq(0.025,0.10,by=0.025) # intere rate sequence
colors = c("red","blue","green","orange") #colors of interest rate seq
index = 1:length(int_seq)
# AV Simple Interest (all good)
avSimple = function(i,t){
av = (1 + (i * t))
return(av)}
# Plot range for y-axis (all good)
yrange = c(avSimple(min(int_seq),min(t)) * 0.95,
avSimple(max(int_seq),max(t)) * 1.05)
plot(t, type="n", main = "AV Simple Interest", xlab = "Time",
ylab = "AV", ylim = yrange)
# for (i in index)
# lines(t,avSimple(int_seq[i],t), col = colors[i])
# Adds legend to plot for different interest rates
# !!This is where I need the help, not sure best way to approach!!
labs <- sprintf('i =: %s%%', c(0, int_seq))
labs2 <- paste0(c(0, int_seq), '%')
legend('topleft', legend = labs, col = colors, lty = 1, title = 'normal')
l <- legend('top', legend = rep('i =:', length(labs)), lty = 1,
col = colors, text.width = max(strwidth(labs)) + 1,
title = 'right-justified')
text(l$rect$left + l$rect$w, l$text$y, labs2, pos = 2)
legend('topright', legend = labs, text.col = colors, title = 'colored')
legend('bottom', legend = labs, col = colors, lty = 1, horiz = TRUE,
cex = .7, title = 'horizontal')