In the last line of the example below, I had to manually try a couple of different values for pos before I found the 'correct' value that was just outside of the labels that had already been plotted in the previous line. Is there a way to find out that proper value of pos automatically?
dev.off()
windows(width = 8, height = 6)
par(mai = c(0.3, 2.5, 0.3, 0.3)) #bottom, left, top and right
set.seed(42)
plot(rnorm(15,10,1),rnorm(15,10,1), type = "p",
ylim = c(5,15), xlim = c(5,15), xlab = "", ylab = "",
xaxt = "n", yaxt = "n", yaxs="i", xaxs="i")
axis(2, at = c(5,10,15), labels = c("This one", "Particularly long one", "two"), las = 2)
axis(2, at = 10, pos = 2, labels = "Y Axis Label", font = 2, tick = FALSE, cex.axis = 1.5)
You can grab par(usr)[1] and subtract the strwidth of your long label to get the position:
dev.off()
windows(width = 8, height = 6)
par(mai = c(0.3, 2.5, 0.3, 0.3)) #bottom, left, top and right
set.seed(42)
plot(rnorm(15, 10, 1),rnorm(15, 10, 1), type = "p",
ylim = c(5, 15), xlim = c(5, 15), xlab = "", ylab = "",
xaxt = "n", yaxt = "n", yaxs= "i", xaxs= "i")
axis(2, at = c(5, 10, 15),
labels = c("This one", "Particularly long one", "two"), las = 2)
# get the position based on the long string width and par('usr')[1]
pos <- par('usr')[1] - strwidth("Particularly long one")
axis(2, at = 10, pos = pos,
labels = "Y Axis Label", font = 2, tick = FALSE, cex.axis = 1.5)
Of course, if you resize the image interactively after this, all bets are off.
Related
I want to plot in R several panels with data measured along a sediment core (see image below). Next to the plots, I want to add a photo of that sediment core, aligned to the exact y coordinates as the plots (to be able to identify if a certain layer in the photo corresponds to a peak in some element in the plot).
The piece of code below produces de multipanel plot plus the photo (see below as well). As you can see using the tape measure in the photo, the y coordinates of the plots do not match the coordinates of the photo.
op <- par(mfrow = c(1,4), oma = c(5,4,2,0) + 0.1, mar = c(0,0,4,1) + 0.1, pch = 20)
plot(y = -curian3_scores$Sample, x = curian3_scores$RC1, xaxt = "n", type = "o", pch =16, ylab = "", xlab = "", lwd = 1.5, col = "blue", ylim = c(-1197.744, -40), cex.axis = 1.2)
axis(3, cex.axis = 1.2)
mtext(side = 3, text = var.PC1, line = 2.2, cex = 0.9)
mtext(side = 2, text = "Depth (mm)", line = 3, cex = 0.9)
plot(y = -curian3_scores$Sample, x = curian3_scores$RC2, xaxt = "n", yaxt = "n", type = "o", ylab = "", xlab = "", lwd = 1.5, col = "red", ylim = c(-1197.744, -40), cex.axis = 1.2)
axis(3, cex.axis = 1.2)
mtext(side = 3, text = var.PC2, line = 2.2, cex = 0.9)
plot(y = -curian3_scores$Sample, x = curian3_scores$RC3, xaxt = "n", yaxt = "n", type = "o", ylab = "", xlab = "", lwd = 1.5, col = "darkgreen", ylim = c(-1197.744, -40), cex.axis = 1.2)
axis(3, cex.axis = 1.2)
mtext(side = 3, text = var.PC3, line = 2.2, cex = 0.9)
# Charge the image as an R object with the "JPEG" package
library(jpeg)
my_image=readJPEG("~/Documents/FEINA/POSTDOCTORAT/RESILCOAST/ARTICLES/Carbon_persistence/Data_mining/CoreScanner/Core_Images_for_R/CURIAN3a_8.jpg")
# Set up a plot area with no plot
plot(y = -curian3_scores$Sample, x = curian3_scores$RC3, type = "n", axes = F, ylab = "", xlab = "")
# Get the plot information so the image will fill the plot box, and draw it
lim <- par()
rasterImage(my_image, xleft = lim$usr[1], ybottom = lim$usr[3], xright = lim$usr[2], ytop = lim$usr[4])
par(op)
Any ideas to make the photo's and plots' coordinates to match? If the ylim in each plot worked, I think this would be it... however, I think they're overruled for some reason...
Hi can anyone see what is the problem with the code below?
output$zscore_chart <- renderPlot({
xvals <- 2:186
req(input$countrySelectZScore)
idx_country = which(input$countrySelectZScore == esiCountries)
max_comp_z <- max(esiData_DF[idx_country, 2:186], na.rm = TRUE)
overall_max_z <- max(max_comp_z, na.rm = TRUE)
foo = ts(esiData_DF[idx_country, 2:186], frequency = 12, start = 2001)
dates = seq(as.Date("2001-01-01"), by = "month", along = foo)
plot(x = 2:186, y = esiData_DF[idx_country, 2:186], type = "l",
xlab = "", ylab = "", col = "grey20", ylim = c(-2, overall_max_z),
lwd=3,las=2)
mtext("Quarterly percentage changes", side = 3, adj = 0, line = 0.1,
cex = 1, font = 0.5)
axis(1, at = xvals, label = dates, cex.axis = 1, las = 2)
mtext("Economic Sentiment Indicators", side = 3, adj = 0,
line = 1.2, cex = 2, font = 2)
legend(
"bottom",
lty = c(1,1),
lwd = c(3,3),
col = c("grey20", "green2"),
legend = c("Economic Sentiment Indicator", "GDP growth"),
bty = "n",
xjust = 0.5,
yjust = 0.5,
horiz = TRUE
)
}, height = 525)
esiData_DF is the DF used to index and plot the correct data. The dataframe has the country names down the left hand side with the dates, monthly across the top. I need the plot to render but it wont when I run the app. Any ideas?
The data continues to the right, up to May 2017 monthly.
So i have a dataframe that looks like this:
I am trying to plot this so that the 'cancers' are on the x axis and then the 'oddsRatio' and 'foldIncrease' are both y-axis parameters. Ideally I have a bar graph with oddsRatio and foldIncrease for each cancer next to each other, and being distinguished by color.
This is the closest I can get:
Using the following code:
cancers = c("All Cancers", "SCLC", "Lu SCC", "Lung AC", "Larynx", "Pharynx Oral", "Cavity", "Esophageal SCC", "Esophageal AC", "Bladder", "Liver", "Cervix", "Kidney", "Pancreas")
oddsRatio = c(1, 111.3, 103.5, 21.9, 13.2, 6.6, 4.2, 3.9, 3.9, 3.8, 2.9, 1.8, 1.7, 1.6)
foldIncrease = c(1.15464695360441, 0.858680717668245, 1.29986125563649, 4.56755645705811, 2.52922152922153, 0.818596228001855, 0.892133516869108, 1.04842410881178, 1.01791768793961, 1.1423932173087, 1.1871100629828, 0.857694671793762, 1.39573948596081, 1.33458517681876)
cancerData = data.frame(cancers, oddsRatio, foldIncrease)
par(mar = c(5,5,2,5))
with(cancerData, plot(cancers, oddsRatio, type="scatter", col="red3",
ylab='Odds Ratio',
ylim=c(0,150)))
par(new = T)
with(cancerData, plot(cancers, foldIncrease, pch=16, axes=F, xlab=NA, ylab=NA, cex=1.2))
axis(side = 4)
mtext(side = 4, line = 3, 'Fold Increase')
To clarify I am looking for this:
Is this what you are wanting? (note, I used ggplot2 rather than base)
library(tidyverse)
tidy <- cancerData %>%
gather(stats, val, -cancers)
ggplot(tidy, aes(cancers, val)) +
geom_bar(aes(fill = stats), stat = "identity", position = "dodge")
Edit
Okay, so generally I don't think this is a great idea. See here for why. But if you really want to, the below should do it for you.
vars <- length(unique(cancerData$cancer))
par(mar = c(4, 4, 4, 6))
plot(1:vars, seq(0, 120, length = vars),
type = "n",
main = "Odds Ratios and Fold Increase",
bty = "n",
xaxt = "n",
xlab = "Cancers",
ylab = "Odds Ratios")
rect(1:vars - 0.25, 0, 1:vars, cancerData$oddsRatio, col = "blue")
axis(1, at = 1:vars, labels = unique(cancerData$cancer))
par(new = TRUE)
plot(1:vars, seq(0, 5, length = vars),
type = "n",
xaxt = "n",
yaxt = "n",
bty = "n",
xlab = "",
ylab = "")
rect(1:vars, 0, 1:vars + 0.25, cancerData$foldIncrease, col = "red")
axis(4)
mtext("Fold Increase", side = 4, line = 3)
legend("topright",
fill = c("blue", "red"),
legend = c("Odds Ratio", "Fold Increase"),
box.lwd = 0)
I want to have my titles be above my points in a pdf plot. It seems R thinks my title is wider than my plot area even though I have my right and left plot margins set to zero.
x <- seq(from = 0.1, to = 0.9, by = 0.1)
xtitle <- c("0.1","0.2","0.3","0.4","0.5","0.6","0.7","0.8","0.9")
pdf("testpdfopts.pdf", width = 16)
par(mar = c(0, 0, 1, 0)) # only need margin at top for title
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
for (i in 1:length(x)) {
title(xtitle[i],adj=x[i],cex.main=1)
}
dev.off()
Thanks in advance for any assistance
I am sort of confused with what you are trying to do. Maybe I should put my comment into complete code:
x <- seq(from = 0.1, to = 0.9, by = 0.1)
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
axis(3, at = 1:9/10)
Is this equivalent to what you aim to achieve?
You can get character labels too:
x <- seq(from = 0.1, to = 0.9, by = 0.1)
plot(
x,
rep(0.9,length(x)),
xlim = c(0, 1),
ylim = c(0, 1),
cex = 1,
xaxt = "n",
yaxt = "n",
xlab = "",
ylab = ""
)
axis(3, at = 1:9/10, labels = letters[1:9])
Following up this question: pseudocolors in R
I've found a way to create the pseudocolour images with a colour key. However, I'm stuck with adding some text to this key (e.g., "low", "mid", "high" along with tickmarks at the ends an in the middle).
The short version of the story (as an MWE), would be:
library(RColorBrewer)
pal <- colorRampPalette(brewer.pal(9, "YlOrBr"), space = 'rgb')(256)
layout(matrix(c(1,2), nrow = 1), widths = c(4,1), heights = c(4,4))
layout.show(2)
par(mar = c(0,0,0,0))
image(t(matrix(1:30, ncol = 1, nrow = 30)),
col = pal, xaxt = "n", yaxt = "n", frame.plot = FALSE)
par(mar = c(0,0.1,0,0))
image(t(matrix(1:30, ncol = 1, nrow = 30)),
col = pal, xaxt = "n", yaxt = "n", frame.plot = FALSE)
So the aim is to end tickmarks with text on the left part of the image.
Thanks in advance for any help!
I didn't see the point of the layout but thought you could just increase your margin for the first image call and leave out the second one? You wanted "low", "mid", "high" along with tickmarks at the ends an[d] in the middle which I found confusing. Perhaps this will further the discussion:
layout(matrix(c(1,2), nrow = 1), widths = c(4,1), heights = c(4,4))
layout.show(2)
par(mar = c(0,0,0,2))
image(t(matrix(1:30, ncol = 1, nrow = 30)),
col = pal, xaxt = "n", yaxt = "n", frame.plot = FALSE)
axis(4, at=(30:1)/30, labels=1:30, cex.lab=0.6)