R barplot outside region - r

So I've created a barplot for some data I have with the following code:
plot <- barplot(data,
beside = TRUE,
col = c("red", "blue", "green"),
space = c(0, 0.4),
width = 0.2,
xlim = c(0, 2),
ylim = c(0, 1.1),
legend = c("KNN", "MF1", "MF2"),
args.legend = list(x = 2.7, y = 1.2),
yaxt = 'n',
xpd = TRUE,
srt = 90
)
text(x = plot,
y = data + 0.05,
labels = as.character(round(data, digits = 2)),
srt = 90,
xpd = TRUE
)
I think the plot looks neat, but... It does not fit the region (I think at least). Are there any ways to keep the width of the bars in picture 1 and still show all 8 groups? My solution so far is to reduce the width of the bars as shown in picture 2.
Picture 1
Picture 2

Related

My layout doesn't allow me to show xlab and ylab

It looks like something simple I am missing but have no idea how to deal with this.
So I used a layout() function and I managed to get the layout as I wanted as below picture. Iris data was used in my coding.
Problem is, it does not show me the x label and y label on the output when I use plot() functions after this. And xaxis and yaxis for plot() looks overlapping. I am not sure how to deal with this problem.
There was no problem for x and y labelling before introducing plot.new() and par() to set up the main name of my diagram. (i.e. before I use the code from plot.new() to title(), xlab and ylab were shown)
I used 6 different plots in my original code, including, the plot.new() for title(), but I omitted the rest of them for convenience
Here is my code below,
x <- iris$Sepal.Length
y <- iris$Species
x_min <- min(iris$Sepal.Length)
x_max <- max(iris$Sepal.Length)
y_min <- min(iris$Sepal.Width)
y_max <- max(iris$Sepal.Width)
layout(matrix(c(1,1,1,1,1,1,
2,2,3,3,4,4,
5,5,5,6,6,6), nc=6, byrow = TRUE), heights=c(lcm(1),1,1,1,1))
layout.show(6)
par("mar"=c(1,1,1,1,1,1))
plot.new()
plot.window(xlim=c(0,1), ylim=c(0,1))
text(x=0.5,y=0.5,"scatter and density plots for Sepal and Length and Sepal Width" ,font=2, cex=1.5)
plot(...)
You can use the xlab and ylab arguments in title. However, the way you have constructed the plot means that when you reset par at the end, these are drawn off the page due ti their position relative to your custom axis. If you simply leave par alone, you get:
den1 = density(CDE1$V1)
den2 = density(CDE1$V2)
col1 = hsv(h = 0.65, s = 0.6, v = 0.8, alpha = 0.5)
col2 = hsv(h = 0.85, s = 0.6, v = 0.8, alpha = 0.5)
plot.new()
plot.window(xlim = c(25,65), ylim = c(0, 0.14))
axis(side = 1, pos = 0, at = seq(from = 25, to = 65, by = 5), col = "gray20",
lwd.ticks = 0.25, cex.axis = 1, col.axis = "gray20", lwd = 1.5)
axis(side = 2, pos = 25, at = seq(from = 0, to = 0.14, by = 0.02),
col = "gray20", las = 2, lwd.ticks = 0.5, cex.axis = 1,
col.axis = "gray20", lwd = 1.5)
polygon(den1$x, den1$y, col = col1, border ="black",lwd = 2)
polygon(den2$x, den2$y, col = col2, border ="black",lwd = 2)
text(52, 0.10, labels ="CDET", col =col1, cex = 1.25,font=2)
text(35, 0.03, labels ="SDFT", col =col2, cex = 1.25,font=2)
title(main = "Gestational Day 100/283",
xlab = "Fibril Diameter (nm)",
ylab = "density")
Of course, you could get a similar plot with less code and much easier adjustments using ggplot:
library(ggplot2)
ggplot(tidyr::pivot_longer(CDE1, 1:2), aes(value, fill = name)) +
geom_density() +
scale_fill_manual(values = c(col1, col2), labels = c("CDET", "SDFT")) +
scale_x_continuous(breaks = seq(25, 65, 5), limits = c(25, 65)) +
scale_y_continuous(breaks = seq(0, 0.14, 0.02), limits = c(0, 0.14)) +
theme_classic(base_size = 16) +
labs(title = "Gestational Day 100/283", x = "Fibril Diameter (nm)",
fill = NULL) +
theme(plot.title = element_text(hjust = 0.5))
Data used
Obviously, we don't have your data, so I had to create a reproducible approximation:
set.seed(123)
CDE1 <- data.frame(V1 = rnorm(20, 47.5, 4), V2 = rnorm(20, 44, 5))

How to customise dates (years) on the x-axis in R

I am struggling to customise the jump size on the x-axis in R.
Current code:
par(mfrow = c(2,2))
r.star.ts.sp <- ts(r.star.sp, frequency = 4, start = c(1978,1), end = c(2018, 1))
# Big drop in r* around 123th quarter equivalent to 2008:Q4 / 2009:Q1
trendgrowth.ts.sp <- ts(trendgrowth.sp, frequency = 4, start = c(1978,1), end = c(2018, 1))
plot.ts(r.star.ts.sp,
ylim = c(-3, 4), xlab = " ", ylab = " ", axes = F, col = "blue")
lines(trendgrowth.ts.sp, lty = 2, col = "red")
abline(h = 0, lty = 2)
title(main ="r* and Trend Growth", line = 0.5, font.main = 3)
box()
axis(4)
axis(1)
legend("bottomleft", legend = c("r*", "Trend Growth (g)"),
bty = "n", lty = c(1,2), col = c("blue", "red"), horiz = F, text.col = "black",
cex = 1, pt.cex = .5, inset = c(0.02, 0.02))
# -------------------------------------- #
# Plot output gap and real rate gap
# -------------------------------------- #
outputgap.ts.sp <- ts(outputgap.sp, frequency = 4, start = c(1978,1), end = c(2018, 1))
realrategap.ts.sp <- ts(realrategap.sp, frequency = 4, start = c(1978,1), end = c(2018, 1))
plot.ts(outputgap.ts.sp, ylim = c(-20, 15), xlab=" ", ylab=" ", axes = F, col="blue")
lines(realrategap.ts.sp, lty = 2, col = "red")
abline(h = 0, lty = 2)
legend("topright", legend = c("Output Gap", "Real Rate Gap"),
bty = "n", lty = c(1,2), col = c("blue", "red"), horiz = F, text.col = "black",
cex = 1, pt.cex = .5, inset = c(0.02, 0.02))
title(main = "Output Gap and Real Rate Gap", line = 0.5, font.main = 3)
box()
axis(side = 4)
axis(side = 1)
How would one specify the years on the x-axis from 1975 to 2020 with jumps of 5 years?
Furthermore, (off-topic) I need two plots next to each other, but I feel that par(mfrow = c(2,2)) is not the correct statement. However, changing it into par(mfrow = c(1,2)) creates abnormal large figures.
Thanks!
The OP has requested to specify the years on the x-axis from 1975 to 2020 with jumps of 5 years.
This can be achieved by
axis(1, at = seq(1975L, 2020L, by = 5L))
However, the result may depend on the mfrow parameter. Here is a a dummy example using par(mfrow = c(2, 2)):
Note that the x-axis of the left graph was created by axis(1) while the x-axis of the right graph was created by axis(1, at = seq(1975L, 2020L, by = 5L)). Also note the large white space below the two graphs.
With par(mfrow = c(1, 2)) the result becomes
Here, the right graph shows unlabeled ("minor") tick marks. This is explained in the mfrow section of ?par: In a layout with exactly two rows and columns the base value of "cex" is reduced by a factor of 0.83. So, font size is reduzed by 17% per cent which allows to label all tick marks without overplotting.

How can I plot legend symbols and labels on a different row in R?

I'm trying to plot a legend in base R with the symbols horizontally and the corresponding labels underneath the symbols on the next row. The legend will be plotted in the margins (not included in example data). Is there a way to use graphical parameters to solve this with the legend() function? Otherwise I will try the text labels, but I prefer a more manageable approach.
I have this example data:
plot(c(1,2,3,4,5), c(1,2,3,4,5), xlim=c(0,5), ylim=c(0,5), main = "", xlab = "", ylab = "")
legendEntries <- c(0.05, 0.1, 0.15, 0.2, 0.25) # which values in legend
legendSizes <- sqrt( legendEntries / pi ) * 10 # calculate pch size
legend(1, 2, title="", horiz = T, legend=legendEntries, col="black", pch=rep(21,5),
pt.bg = "#ff166c", pt.cex = legendSizes, bty = "n")
And want to create something like this:
Thanks!
Paul
(edit: added picture in text and extra info)
You can plot separately points and text.
Something like:
# Make the basic plot
plot(c(1,2,3,4,5), c(1,2,3,4,5), xlim=c(0,5), ylim=c(0,5), main = "", xlab = "", ylab = "")
# set up the legend entries and sizes
legendEntries <- c(0.05, 0.1, 0.15, 0.2, 0.25) # which values in legend
legendSizes <- sqrt( legendEntries / pi ) * 10 # calculate pch size
# plot the legend points
points(y = rep(1, 5), x = seq(3,4, 0.25), pch = 21, cex = sqrt( legendEntries / pi ) * 10,
bg = "#ff166c")
# plot the text
text(y = rep(0.7, 5), x = seq(3,4, 0.25),
labels = legendEntries)
For Plotting outside of the plot region (i.e. on the margins), you can use the xpd parameter as xpd = TRUE:
plot(c(1,2,3,4,5), c(1,2,3,4,5), xlim=c(0,5), ylim=c(0,5), main = "", xlab = "", ylab = "")
legendEntries <- c(0.05, 0.1, 0.15, 0.2, 0.25) # which values in legend
legendSizes <- sqrt( legendEntries / pi ) * 10 # calculate pch size
points(y = rep(-0.8, 5), x = seq(1,2, 0.25), pch = 21, cex = sqrt( legendEntries / pi ) * 10,
bg = "#ff166c", xpd = TRUE)
text(y = rep(-1, 5), x = seq(1,2, 0.25),
labels = legendEntries, xpd = TRUE)

45 degrees x axis labels in barplot

I know this type of question has been posted several times, but I tried all different suggestions and nothing works for me. I would like to have the x-axis labels on my bar plot positioned at 45 degrees. My code at the moment is like this:
barplot(t(all.vac_models01[1:28,3:4]), ylab = expression("Proportion of "*italic("R"^"2")),
las=2, cex.names = 0.9,
legend.text = gsub("prop_attributed_to_visit", "Intraindividual",
gsub(pattern = "prop_attributed_to_patientID",
replacement = "Interindividual", colnames(all.vac_models01[1:28,3:4]))),
args.legend = list(x= 30, y = 1.3, xpd = T, horiz = T, bg = "white", bty ="o", box.lwd = 0))>
Try this:
x <- barplot(t(all.vac_models01[1:28,3:4]), ylab = expression("Proportion of "*italic("R"^"2")),
las=2, cex.names = 0.9,
legend.text = gsub("prop_attributed_to_visit", "Intraindividual",
gsub(pattern = "prop_attributed_to_patientID",
replacement = "Interindividual", colnames(all.vac_models01[1:28,3:4]))),
args.legend = list(x= 30, y = 1.3, xpd = T, horiz = T, bg = "white", bty ="o", box.lwd = 0),
xaxt="n")
labs <- names(t(all.vac_models01[1:28,3:4]))
text(cex=1, x=x, y=-1.25, labs, xpd=TRUE, srt=45, pos=2)
Assigning the barplot call to x allows you to store the position of the labels. Be sure to specify xaxt="n" so that the labels are not printed initially.

how to unify legends in plot3d?

I saw the following code in an example of plot3d:
par(mfrow = c(2, 2))
# keep ratios between x- and y (scale = FALSE)
# change ratio between x- and z (expand)
persp3D(z = volcano, x = 1: nrow(volcano), y = 1:ncol(volcano),
expand = 0.3, main = "volcano", facets = FALSE, scale = FALSE,
clab = "height, m", colkey = list(side = 1, length = 0.5))
# ribbon, in x--direction
V <- volcano[, seq(1, ncol(volcano), by = 3)] # lower resolution
ribbon3D(z = V, colkey = list(width = 0.5, length = 0.5,
cex.axis = 0.8, side = 2), clab = "m")
# ribbon, in y-direction
Vy <- volcano[seq(1, nrow(volcano), by = 3), ]
ribbon3D(z = Vy, expand = 0.3, space = 0.3, along = "y",
colkey = list(width = 0.5, length = 0.5, cex.axis = 0.8))
This prints four plots, but they each have their own legend.
I want to create similar 3d histograms, only my "Z" have all the same range, and I want to use just a single legend.
So what I want to do is:
Be able to draw just the legend (so I can save it to a file) for all unified histograms, where it is printed horizontally.
Make all legends in all small plots disappear.
I would also appreciate just an answer to one of these questions.

Resources