Polygon function creates strange shape - r

I'm trying to plot multiple distributions on the same plot. For some reason when I use the polygon function, it doesn't sit on the x-axis, and starts to levitate.
Grateful for any advice on how to stop this!
x <- seq(0,5,length=1000)
plot(x = x,
y = dnorm(x, 1.5, 0.4),
type = "l",
col = "white",
axes = FALSE,
mgp = c(2, 2, 2),
ylim=c(0,2), # Set limit of y-axis
frame.plot=TRUE,
xlab = "theta",
ylab = "plausibility",
font.main = 1,
main=paste("Distributions"),
lwd=2
)
polygon(x,dnorm(x, 1.5, 0.4),col=1,border = NULL)
polygon(x,dnorm(x, 1, 0.5),col=2,border = NULL)

As the documentation of ?polygon states
x, y vectors containing the coordinates of the vertices of the polygon.
We have to add 0 as a vertex to both the x and the y coordinates.
polygon(x=c(0, x), y=c(0, dnorm(x, 1.5, 0.4)), col=1, border=NULL)
polygon(x=c(0, x), y=c(0, dnorm(x, 1, 0.5)), col=2, border=NULL)
Result

Related

Gamma PDF plots

I need help in plotting gamma distribution PDFs in R or RStudio. I have four different gamma distributions listed below. I want to plot their PDFs on the same axis with different colours and also add a legend.
gamma(0.5,0.33)
gamma(2.0,0.88)
gamma(2.4,1.22)
gamma(1.8,1.10)
This should get you what you want, but be careful with the parametrization of rate and scale = 1/rate (use just one).
x <- (1:1000)/100
y1 <- dgamma(x = x, 0.5, 0.33)
y2 <- dgamma(x = x, 2.0, 0.88)
y3 <- dgamma(x = x, 2.4, 1.22)
y4 <- dgamma(x = x, 1.8, 1.10)
pdf(file = 'my-gamma-plot.pdf')
plot(x, y1, type = 'l')
lines(x, y2, type = 'l', col = 2)
lines(x, y3, type = 'l', col = 3)
lines(x, y4, type = 'l', col = 4)
legend("topright",
legend = c('gamma1', 'gamma2', 'gamma3', 'gamma4'),
col = c(1:4),
lty = 1, cex = 0.8)
dev.off()
A base R option with curve
f1 <- function(x) dgamma(x, 0.5, 0.33)
f2 <- function(x) dgamma(x, 2, 0.88)
f3 <- function(x) dgamma(x, 2.4, 1.22)
f4 <- function(x) dgamma(x, 1.8, 1.1)
curve(f1, 0, 10)
curve(f2, 0, 10, add = TRUE, lty = "dotdash")
curve(f3, 0, 10, add = TRUE, lty = "dashed")
curve(f4, 0, 10, add = TRUE, lty = "dotted")
legend(
"center",
legend = c("gamma(0.5,0.33)", "gamma(2,0.88)", "gamma(2.4,1.22)", "gamma(1.8.1.1)"),
box.lty = 0,
cex = 1.5,
lty = c("solid", "dotdash", "dashed", "dotted")
)

R - How do I line up axes between a boxplot and matplot?

I have created a side-by-side plot in R where both plots are supposed to use the same y-axis. However, the plot on the left is a boxplot and the plot on the right is a matplot and in both plots I have set the same y-axis range ylim = c(0, YMAX). Unfortunately, as you can see below, these plots do not appear to use the same layout range --- the barplot takes the range right to the edges of the axis whereas the matplot has a buffer at each edge of the axis. Consequently, the y-axes on the plots do not line up as intended.
#Create layout for plot
LAYOUT <- matrix(c(rep(1, 2), 2:3), nrow = 2, ncol = 2, byrow = TRUE);
layout(LAYOUT, heights = c(0.1, 1));
#Create plot matrix
par(mar = c(0.5, 2.1, 0.5, 2.1), mgp = c(3, 1, 0), las = 0);
plot.new();
text(0.5,0.5, 'Barplot and Violin Plot', cex = 1.2, font = 2);
par(mar = c(5.1, 4.1, 2.1, 2.1), mgp = c(3, 1, 0), las = 0);
#Generate data for plot
x <- 1:100
y <- rchisq(100, df = 40);
#Generate plots
DENS <- density(y);
YMAX <- 1.4*max(y);
barplot(y, names.arg = x, ylim = c(0, YMAX));
matplot(x = cbind(-DENS$y, DENS$y), y = DENS$x,
type = c('l', 'l'), lty = c(1, 1),
col = c('black', 'black'),
xlim = c(-max(DENS$y), max(DENS$y)),
ylim = c(0, YMAX),
xlab = 'Density', ylab = '');
How do I adjust this plot to line up the y-axes? (Ideally I would like the plot on the right to put the ticks right to the edge of the axis just as is the case on the left.)
The comment by user20650 solves my problem, so I am going to take the liberty of expanding it into a larger answer and linking to some documentation I found on the problem. According to some lecture notes on the base graphics parameters, some of the base plots in R add a 6% buffer beyond the specified axis range by default. The commands xasx = 'i' and yasx = 'i' inhibit this buffer (on the x and y axes respectively), so that the axis limits go right to the edge of the axis.
Applying this solution to the y-axis in the present problem (we do not apply it to the x-axis, since we want to retain the buffer on that axis) gives the following commands and plot. As can be seen from the plot, the y-axes in the two plots now line up correctly. Hooray!
#Create layout for plot
LAYOUT <- matrix(c(rep(1, 2), 2:3), nrow = 2, ncol = 2, byrow = TRUE);
layout(LAYOUT, heights = c(0.1, 1));
#Create plot matrix
par(mar = c(0.5, 2.1, 0.5, 2.1), mgp = c(3, 1, 0), las = 0);
plot.new();
text(0.5,0.5, 'Barplot and Violin Plot', cex = 1.2, font = 2);
par(mar = c(5.1, 4.1, 2.1, 2.1), mgp = c(3, 1, 0), las = 0);
#Generate data for plot
x <- 1:100
y <- rchisq(100, df = 40);
#Generate plots
DENS <- density(y);
YMAX <- 1.4*max(y);
barplot(y, names.arg = x, ylim = c(0, YMAX));
matplot(x = cbind(-DENS$y, DENS$y), y = DENS$x, yaxs = 'i',
type = c('l', 'l'), lty = c(1, 1),
col = c('black', 'black'),
xlim = c(-max(DENS$y), max(DENS$y)),
ylim = c(0, YMAX),
xlab = 'Density', ylab = '');

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)

Plot color of values based on where they fall on a 1:1 line - R

How would one set the color of data points depending if they above or below a 1:1 line?
It's very simple to do this for a vertical or horizontal line (abline), but how would one do this for a 1:1 line?
Here is how to do it for a horizontal line:
x <- c(2,4,6,8,10)
y <- c(2,4.9,5,9,12)
df <- cbind(x,y)
plot(df[,1], df[,2], xlim=c(0,15), ylim=c(0,15), pch = 21,
bg =ifelse(df[,2]<=5,"black","red"), col = "black", cex = 1.5,
cex.axis = 1.4, cex.lab = 1.4, xlab = "x", ylab = "y")
abline(h=c(5.0),lty=2)
How would one do this for a 1:1 line where:
abline(0, 1)
Just test for x > y or equivalently y <= x:
plot(df[,1], df[,2], xlim=c(0,15), ylim=c(0,15), pch = 21,
bg =ifelse(df[,2] <= df[,1],"black","red"), col = "black", cex = 1.5,
cex.axis = 1.4, cex.lab = 1.4, xlab = "x", ylab = "y")
abline(0, 1)
This solution below will plot point colors according to how far they are from the abline.Simply calculate the deviation from the abline, then convert it to a color gradient and use it in the col argument in plot:
x <- c(2,4,6,8,10)
y <- c(2,4.9,5,9,12)
deviation <- abs(y-x)
rbPal <- colorRampPalette(c('blue','red'))
data_col=rbPal(10)[as.numeric(cut(deviation,breaks = 10))]
df <- cbind(x,y,deviation)
plot(x, y, xlim=c(0,15), ylim=c(0,15), pch = 21, col=data_col, bg=data_col)
abline(0, 1)

How to add axis labels to a simple.scatterplot (UsingR)

The package UsingR has some great out of the box plotting tools. However, using the simple.scatterplot function I can't figure out how to add axis labels.
library(UsingR)
simple.scatterplot(iris$Sepal.Length, iris$Sepal.Width, xlab='hello axis')
Error in plot.default(x, y, xlim = xrange, ylim = yrange, xlab = "x", :
formal argument "xlab" matched by multiple actual arguments
The graph can of course be produced without using the xlab arg, and I tried using the mtext command, but the label ends up in the middle of the page.
mtext(side=1, text='hello axis')
I tried editing the function itself without success either:
mysimple.scatterplot <- function (x, y)
{
def.par <- par(no.readonly = TRUE)
n <- length(x)
xhist <- hist(x, sqrt(n), plot = FALSE)
yhist <- hist(y, sqrt(n), plot = FALSE)
top <- max(c(xhist$counts, yhist$counts))
xrange <- c(min(x), max(x))
yrange <- c(min(y), max(y))
nf <- layout(matrix(c(2, 0, 1, 3), 2, 2, TRUE), c(3, 1),
c(1, 3), TRUE)
layout.show(nf)
par(mar = c(3, 3, 1, 1))
plot(x, y, xlim = xrange, ylim = yrange, xlab = 'Hello X-axis', ylab = 'Hello Y-axis',
...)
abline(lm(y ~ x))
par(mar = c(0, 3, 1, 1))
barplot(xhist$counts, axes = FALSE, ylim = c(0, top), space = 0,
col = gray(0.95))
par(mar = c(3, 0, 1, 1))
barplot(yhist$counts, axes = FALSE, xlim = c(0, top), space = 0,
col = gray(0.95), horiz = TRUE)
par(def.par)
}
The cause is here:
layout.show(nf)
par(mar = c(3, 3, 1, 1)) # <-- Here
plot(x, y, xlim = xrange, ylim = yrange, xlab = 'Hello X-axis', ylab = 'Hello Y-axis',
...)
The margins are changed to a small value thus the labels are not in the plot, they are outside of the area.

Resources