Legend box width not correct when using par - r

I have the problem , that my legend is too large, my code:
par(mfrow=c(1,2))
hist(alvsloss,breaks = 100, freq=F,main="Histogramm,
density curve (gaussian kernel) \n and fitted normal distribution of Allianz simple losses ",xlim=c(-0.15,0.15),xlab="loss",ylab="density",cex.axis=1.2,cex.lab=1.2)
lines(density(alvsloss), col="black", lwd=2)
curve(dnorm(x, mean = mean(alvsloss), sd = sd(alvsloss)), add=TRUE, col="black",lwd=2,lty="dotted")
legend(-0.155, 30, c("(Gaussian) Kernel density","fitted normal distribution"),lwd=2, cex=0.8,
col=c("black","black"), lty=1:2)
qqnorm(alvsloss,main="normal QQ Plot",cex.axis=1.2,cex.lab=1.2)
qqline(alvsloss)
This gives the following picture:
The problem is, that the legend on the left is too big, how can I control the width of the box? The box is way too large.
data can be found here: http://uploadeasy.net/upload/ocafq.rar

The white space on the right of you legend tells me that you manually widened your plot window. Legends do not scale well when it comes to manual re-sizing.
The solution is opening a plot of the exact size you need before plotting. In Windows, this is done with windows(width=10, height=8). Units are in inches. The surrounding box should now be tighter with the text.
If this is still not satisfactory, you should try:
Reducing the font size of the legend cex=0.7
Removing the box around the legend bty = "n" and using \n to
split your legend onto several lines
You can put your legend even more on the left using "topleft"
instead of coordinates
Here's how I would do it:
legend("topleft",
legend=c("(Gaussian)\nKernel\ndensity","Fitted\nnormal\ndistribution\n"),
bty = "n",lwd=2, cex=0.7, col=c("black","black"), lty=1:2)

Related

legend outside plot in R and use pty="s"

I want to plot a roc curve in R but with legends outside the plot.
I want the axes labels to be from 0-1. So I used pty="s" but I am trying to fit the legend its not working.
par(pty="s",xpd=T, mar=par()$mar+c(0,0,0,3))
plot(g1,main="BPH vs G6", lty=1,xlab="Specificity", ylab="Sensitivity",
lwd=2,cex.main=2,font.axis=2,font.lab=2,cex.lab=2,cex.axis=1.2)
lines(g2, lty=1, col="red", lwd=2)
legend(-0.1,0.8,
legend=c("301+CN","CN"),
lty=c(1,1),col=c("red", "black"),cex=0.5)
I do not want the diagonal line to go outside the plot. Also, I want to increase the legend size, but by adjusting cex its not fitting here.

How to decrease padding between lines and points in R "both" type plots

I have tried to plot a series of points in R, and I use type="b" as a plot option. However, there is a lot of padding (white space) between the points and the lines between them, so much that the line disappears entirely between some points. Her is a picture of how it looks:
I have tried to make the points smaller with the cex plot option, but this does not help, as it only changes the size of the points and not where the lines between the points between these starts and ends. I do not know if this makes a difference, but the symbols I am using are pch=1.
I am interested in knowing if it is possible to reduce this padding, and how you do so. I am not interested in using type=o as a plot option instead.
Any particular reason why you don't want to use type="o"? It seems like the easiest way to get the effect you want:
# Fake data
set.seed(10)
dfs = data.frame(x=1:10, y=rnorm(10))
plot(y~x,data=dfs, type="o", pch=21, bg='white')
pch=21 is a circle marker like pch=1, but with both border and fill. We set the fill to white with bg="white" to "cover up" the lines that go through the point markers.
You can also use cex to change the marker size to avoid overlap and make the lines between nearby points visible:
set.seed(10)
dfs = data.frame(x=1:100, y=cumsum(rnorm(100)))
plot(y~x,data=dfs, type="o", pch=21, bg="white", cex=0.6)
Using a dataframe named dfs this seems to deliver a mechanism for adjusting the surrounding "white halo" to whatever size of point an halo you want by adjusting the 'cex' values of the white and black points :
plot(y~x,data=dfs, type="l")
with(dfs, points(x,y, pch=16,col="white",cex=1.4))
with(dfs, points(x,y,cex=1) )

R - How to not change axis ranges when plotting two factor series

My code:
plot(factor(tData$Interval), tServiceLev, col = "red", type = "l", main =
'Service Level and Call Volume', xlab = "Time Intervals", ylab = "Service Level")
lines(factor(tData$Interval), tServiceLev, type = "l", col = "blue",lwd = 2)
par(new=TRUE)
plot(factor(tData$Interval), tData$Offered, type = "l", axes=FALSE, col = "green")
axis(4)
mtext("Call Volume", 4,1.5)
lines(factor(tData$Interval), tData$Offered, col = "red", lwd=2)
legend("topright", col=c("blue","red"), lty = 1, legend = c("Service Level", "Call Volume"), cex = .85)
When I put on the second plot, it overwrites the left axis completely. Also is there a way to make the actual graph larger and the axis labels closer to the axis range values?
Edit: This is my new graph after I knitted rmd. Call Volume is cut off. I want the time intervals to be as shown, but coloring each data point does not work. I guess part of the confusion is working with factored data which I've never worked with before.
Within the plot() calls, you need to set axes=FALSE. Then you can use axis() subsequently to customize the axes as you wish (using side=1 for bottom, side=2 for left axis).
For the other adjustments, try preceding plot with a call to dev.new(width=8, height=8), for example, launching an 8" by 8" device. Then using par(mai=c(2,2,1,1)) you can set 2" margins at bottom and left, 1" at top and right. Adjust those numbers as needed to get the proper size.
When calling axis, use axis(..., labels=FALSE) to make the axis with ticks, etc. Then print the actual labels using mtext. The lines=.. option within mtext will allow you to set the distance off the axis that the labels plot.
Update: Again, have you tried setting more space for the margin using par(mai=c(bottom,left,top,right)) as I suggested above? Using a larger number for right should give more space for the axis label. Also, try using type='o' to plot makers and lines. Still not understanding the change you'd like to make to the x axis.

Legend objects closer between them in R

I have to plot the following graph in R:
library(TTR)
x.date<-seq(1,num.years,by=20)
x.axis<-list(x1="1900",x2="1920",x3="1940",x4="1960",x5="1980",x6="2000")
plot(Annual.Mean.1, type="l",col="gray48",xaxt="n", xlab="Years",
ylab="Temperature")
grid()
axis(1,x.date,x.axis)
SMA.1<-SMA(Annual.Mean.1,n=10
par(new=TRUE)
lines(SMA.1,col="red",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
SMA.2<-SMA(Annual.Mean.1,n=15)
par(new=TRUE)
lines(SMA.2,col="mediumpurple",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
SMA.3<-SMA(Annual.Mean.1,n=20)
lines(SMA.3,col="blue",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
legend("topleft",legend=c("Average Temperature","SMA 10 years","SMA 15 years","SMA 20 Years"),
text.col=c("black","red","mediumpurple","blue"),col=c("gray48","red","mediumpurple","blue"),
cex=0.7,lty=c(1,1,1,1))
The output is this:
In the above plot, the rectangle which contain the legend is very big; i would like to obtain a smaller rectangle, like in the below plot:
How to do this?
UPDATE
As suggested in the comments, I have modified my code, in order to make it reproducible by anyone:
library(TTR)
set.seed(1)
x.date<-seq(1,111,by=20)
x.axis<-list(x1="1900",x2="1920",x3="1940",x4="1960",x5="1980",x6="2000")
data<-runif(111,-3,3)
plot(data, type="l",col="gray48",xaxt="n",xlab="Years",
ylab="Temperature")
grid()
axis(1,x.date,x.axis)
SMA.1<-SMA(data,n=10)
par(new=TRUE)
lines(SMA.1,col="red",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
SMA.2<-SMA(data,n=15)
par(new=TRUE)
lines(SMA.2,col="mediumpurple",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
SMA.3<-SMA(data,n=20)
lines(SMA.3,col="blue",type="l",lwd="2",xaxt="n",yaxt="n",ann=FALSE)
legend("topleft",legend=c("Average Temperature","SMA 10 years","SMA 15 years","SMA 20 Years"),
text.col=c("black","red","mediumpurple","blue"),col=c("gray48","red","mediumpurple","blue"),
cex=0.7,lty=c(1,1,1,1))
I still having the same problem as explained above.
Reduce the value of your cex parameter in the legend call. You have it at cex=0.7. Try 0.6 or 0.5 (or lower) until you find the best size.
If that doesn't work, another approach is to just remove the box around the legend altogether with parameter bty = "n". If the background of the legend is blocking the lines in the graph, move the legend command up in your code so that it is drawn first and the lines are drawn over top of it.

R: combine mtext() with points() - correct way to specify coordinates?

I want to combine a text I place in the margins with mtext() with a graphics object that I create either using points() or polygon(). The following example roughly works for me with the default plot settings:
plot(1)
mtext("This is a red dot:", side=1, line=2, cex=0.8)
par(xpd=T)
points(1.08, 0.512, pch=15, cex=1.5, col="red")
However, using plot(1:10) instead or prefixing it with windows(8,8) puts the dot in the wrong position, as points() takes user coordinates. Is there a way to get my dot placed correctly independent of plot limits or device size?
I think I have found an answer that works based on the suggestions of #koekenbakker. To make it look pretty, some minor adjustments are still necessary to get the dot in line with the text, but it seems to work well independent of plot size and axis limits (but you cannot resize the plot once created). To do the adjustments on the exact position of the point, I would recommend using fractions of strheight("O", cex=0.8) and strheight("O", cex=0.8) for this example (which uses cex=0.8 for demonstration).
plot(1)
mtext("This is a red dot:", side=1, line=2, cex=0.8, col="green") ## place sample text at bottom of figure
par(xpd=T) ## enable plotting outside plot region
textXPos <- mean(par("usr")[1:2]) ## x position is middle of plot
textYPos <- par("usr")[3] - strheight("O") * 4 ## y position is below bottom of plot (line 2 = 4 * height of letter O)
text(textXPos, textYPos, "This is a red dot:", cex=0.8, col="red", adj=c(0.5, 0)) ## this text overlaps - y position is correct
pointXPos <- textXPos + 0.5 * strwidth("This is a red dot:", cex=0.8) ## text is centred, so need to move half of the text width to the right
points(pointXPos, textYPos, pch=16, col="red") ## still needs minor adjustments to x and y position to make it look nice

Resources