How to put legend outside the plot area? - r

My problem is related to car package.
I create Kernal plot. However, since legend is too big, I would like to move legend outside the plot are, upper or lower?
Otherwise, I tried with cowplot::get_legend( ), but it did not work properly.
library(car)
mtcars$g <- as.factor(mtcars$vs)
densityPlot(mpg,mtcars$g,show.bw=T, kernel=depan,legend=list(location="topleft",title=NULL))

Probably the easiest thing is to not plot the legend using the densityPlot() function but rather add it separately using legend(). The following code is an example of how this can be done. The resulting figure look like this:
library(car)
mtcars$g <- as.factor(mtcars$vs)
par(mar=c(4,4,4,2))
# obtaining results from kernel density and saving results
# need saved values for bandwidth in legend
# also plots the kernel densities
d <- densityPlot(mtcars$mpg,mtcars$g
,show.bw=T
,kernel=depan
,legend=F # no default legend
,col = c('black','blue')
,lty=c(1,2))
# allows legend outside of plot area to be displayed
par(xpd=T)
# defining location based on the plot coordinates from par('usr')
legend(x=mean(par('usr')[c(1,2)]) # average of range of x-axis
,y=par('usr')[4]+0.015 # top of the y axis with additional shift
,legend = c(paste('0 (bw = ',round(d$`0`['bw'][[1]],4),')',sep='') # extract bw values from saved output and
,paste('1 (bw = ',round(d$`1`['bw'][[1]],4),')',sep='')) # formatting similar to default, except with rounding bw value
,ncol=1 # change to 2 if you want entries beside each other
,lty=c(1,2) # line types, same as above
,col=c('black','blue') # colors, same as above
,lwd=1
,xjust = 0.5 # centers legend at x coordinate
,yjust = 0.5 # centers legend at y coordinate
)
par(xpd=F)

Related

How to add text labels to a scatterplot?

Is there a way to add text labels to the points on a scatterplot? Each point has a string associated with it as its label. I like to label only as many points as it can be done withour overlapping?
df = DataFrame(x=rand(100), y=rand(100), z=randstring.(fill(5,100)))
scatter(df.x, df.y)
annotate!(df.x, df.y, text.(df.z))
using StatisticalGraphics package:
using InMemoryDatasets
using StatisticalGraphics
using Random
ds=Dataset(x=rand(100), y=rand(100), z=randstring.(fill(5,100)))
sgplot(ds, Scatter(x=:x,y=:y,labelresponse=:z))
Here is something I wrote for Makie.jl that suited my needs:
Non-overlapping labels for scatter plots
It works best for single line, short text labels, and where all labels have similar lengths with one another. It is still WIP, as I am working to improve it for placement of longer text labels.
Here are some samples of what it can do:
Essentially, you call function viz to plot a scatter chart on your (x, y) data set:
resolution = (600, 600) # figure size (pixels) -- need not be a equal dimension
fontpt = 12 # label font size (points)
flabel = 1.5 # inflate the label size to create some margins
fdist = 0.3 # inflate the max. distance between a label and its
# anchor point before a line is drawn to connect. them.
# Smaller values would create more connecting lines.
viz(x, y, labels; resolution=resolution, flabel=flabel, fdist=fdist, fontpt=fontpt)
where labels is a list containing the text labels for every pair of (x, y) point.
You can use the extra named argument series_annotations in the scatter function. Here us an example where I use "1", "2", etc. as labels:
using Plots
x = collect(0:0.1:2)
y = sinpi.(x)
scatter(x, y, series_annotations = text.(1:length(x), :top))
Avoiding overlaps is more difficult. You could customize your label with empty "" for duplicates where the points are the same, or see for Makie: Makie: Non-overlapping label placement algorithm for scatter plots

How to make a Common legend for multiple plots in R?

How can I make a Common legend for multiple plots? As I have plotted multiple plots but each plot is showing a single legend for itself as if I want to remove it and show a command legend.
And I also want to rename xlim to lon and ylim = lat. How can it be possible in image.plot?
This is my code
set.panel()
par(oma=c( 0,0,0,4)) # margin of 4 spaces width at right hand side
set.panel( 2,2) # 2X2 matrix of plots
# now draw all your plots using usual image command
for ( k in 1:4){
image.plot(lon, lat, pr2)
plot(shape,add=TRUE)
image.plot(lon, lat, pr1)
plot(shape,add=TRUE)
}
par(oma=c( 0,0,0,1))# reset margin to be much smaller.
image.plot( legend.only=TRUE, zlim=c(0,2000),horizontal = TRUE)
image.plot tricked into plotting in margin of old setting
set.panel() #
This is my image showing the plot:

Plot continuous data with discrete colors

I found some similar questions but the answers didn't solve my problem.
I try to plot a time series of to variables as a scatterplot and using the date to color the points. In this example, I created a simple dataset (see below) and I want to plot all data with timesteps in the 1960ties, 70ties, 80ties and 90ties with one colour respectively.
Using the standard plot command (plot(x,y,...)) it works the way it should, as I try using the ggplot library some strange happens, I guess I miss something. Has anyone an idea how to solve this and generate a correct plot?
Here is my code using the standard plot command with a colorbar
# generate data frame with test data
x <- seq(1,40)
y <- seq(1,40)
year <- c(rep(seq(1960,1969),2),seq(1970,1989,2),seq(1990,1999))
df <- data.frame(x,y,year)
# define interval and assing color to interval
myinterval <- seq(1959,1999,10)
mycolors <- rainbow(4)
colbreaks <- findInterval(df$year, vec = myinterval, left.open = T)
# basic plot
layout(array(1:2,c(1,2)),widths =c(5,1)) # divide the device area in two panels
par(oma=c(0,0,0,0), mar=c(3,3,3,3))
plot(x,y,pch=20,col = mycolors[colbreaks])
# add colorbar
ncols <- length(myinterval)-1
colbarlabs <- seq(1960,2000,10)
par(mar=c(5,0,5,5))
image(t(array(1:ncols, c(ncols,1))), col=mycolors, axes=F)
box()
axis(4, at=seq(0.5/(ncols-1)-1/(ncols-1),1+1/(ncols-1),1/(ncols-1)), labels=colbarlabs, cex.axis=1, las=1)
abline(h=seq(0.5/(ncols-1),1,1/(ncols-1)))
mtext("year",side=3,line=0.5,cex=1)
As I would like to use ggplot package, as I do for other plots, I tried this version with ggplot
# plot with ggplot
require(ggplot2)
ggplot(df, aes(x=x,y=y,color=year)) + geom_point() +
scale_colour_gradientn(colours= mycolors[colbreaks])
but it didn't work the way I thought it would. Obviously, there is something wrong with the color coding. Also, the colorbar looks strange. I also tried it with scale_color_manual and scale_color_gradient2 but I got more errors (Error in continuous_scale).
Any idea how to solve this and generate a plot according to the standard plot 3 including a colorbar.

R studio: make small plot inside histogram and repeat it for as many times as I need, using par function

I need to make a histogram for my variable which is 'travel time'. And inside that, I need to plot the regression(correlation) data i.e. my observed data vs predicted. And I need to repeat it for different time of day and week(in simple words, make a matrix of such figure using par function). for now, I can draw histograms and arrange that in matrix form but I am facing a problem in inside plot (plotting x and y data together with y=x line, and arranging them within their consecutive histograms plot, in a matrix ). How can I do that, as in the figure below. Any help would be appreciated. Thanks!
One way to do this is to loop over your data and on every iteration create a desired plot. Here is one not very polished example, but it shows the logic how plotting a small plot over larger plot can be done. You will have to tweak the code to get it work in the way you need, but it shouldn't be that difficult.
# create some sample dataset (your x values)
a <- c(rnorm(100,0,1))
b <- c(rnorm(100,2,1))
# create their "y" values counterparts
x <- a + 3
y <- b + 4
# bind the data into two dataframes (explanatory variables in one, explained in the other)
data1 <- cbind(a,b)
data2 <- cbind(x,y)
# set dimensions of the plot matrix
par(mfrow = c(2,1))
# for each of the explanatory - explained pair
for (i in 1:ncol(data2))
{
# set positioning of the histogram
par("plt" = c(0.1,0.95,0.15,0.9))
# plot the histogram
hist(data1[, i])
# set positioning of the small plot
par("plt" = c(0.7, 0.95, 0.7, 0.95))
# plot the small plot over the histogram
par(new = TRUE)
plot(data1[, i], data2[, i])
# add some line into the small plot
lines(data1[, i], data1[, i])
}

Scatter plot in R

I'm fairly new to r and I have to plot the scatter plot with:
residues1 residues2 coovariance
1 1 0.99613318
2 1 0.98771518
3 1 0.98681384
4 1 0.99225447
residue 1 and residue2 as x,y axis and the coovariance is to be color scale rather than height. I have previously used scatter plot 3d but don't know how to plot the third axis as a color scale. Please help .
Thanks
Vibhor
I'm not sure an x-y plot with color per column 3 is the best way to visualize this. If residues2 is a constant, prob. better to leave it out altogether and plot the other values against each other.
Perhaps you could adapt the following to your needs:
df1 <- data.frame(r1=seq(4), r2=rep(1,4),
c1=c(0.99613318, 0.98771518, 0.98681384, 0.99225447) )
### give order (for plotting)
df1 <- within(df1, c2 <- rank(c1))
### create blank plot
with(df1, plot(r1,r2, xlab="residues_1", ylab="residues_2", cex.lab=1.5))
### strongest red to largest color
with(df1, points(r1, r2, cex=15, pch=19, col = rev(heat.colors(4))[c2] ))
### make legend
l1 <- as.matrix(df1[ ,"c1"])
graphics::legend("topright", legend=l1, lty=1, title="covariance", lwd=3,
col = rev(heat.colors(4))[df1$c2], cex=2)
giving:
(I've made the image elements a bit oversize, and manually adjusted dimensions before saving as .png in order to display better on here).

Resources