How to make a Common legend for multiple plots in R? - 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:

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

adding two legends to an image.plot

I am a new R user and I need some help to setup a secondary legend for a map.
Description:
I plotted a map using the image.plot function in the fields Library with x and y axes indicating the coordinates and a color scale with a legend andicating the attitude as describedd by the code line below:
image.plot(x,y,z,col=greyscale,legend.mar=8.5,xlab="",ylab="",main="Lambert2étendu")
Problem:
I added points the the map indicating the locations of two types of recievers with different color and cex for each type. and I want to add a legend under the map to describe each coloration signification
Thank you for help
Use legend for a secondary legend. Increase the bottom margin and add legend with negative inset, i.e. move away from plot:
library(fields)
x<- 1:10
y<- 1:15
z<- outer( x,y,"+")
# plot with extra margin at bottom (7)
par(mar=c(7,4,4,2)+0.1)
image.plot(x,y,z,col=gray.colors(10), xlab='', ylab='')
# create points
xp = sample(1:10,size=5)
yp = sample(1:10,size=5)
points(xp,yp,pch=21,bg=1:2,cex=1:2)
# add legend (might have to change inset if you resize the plot)
legend('bottom', horiz=T, legend=paste('type', 1:2), pt.cex=1:2, pch=21, pt.bg=1:2, xpd=NA, inset=c(0,-1..))

setting mfg in a multi plot prevents drawin on margin

I'm trying to add common axes to a bunch of plots by putting them in the outer margin.
Plots are drawn first in a loop (not in the example) then I wanted to draw axes on the bottom of the two rows of plots.
But drawing the axis outside the plotting region is only possible without mfg being changed. How can I enable out-of-plot-drawing after changing mfg?
par(mfrow=c(2,2),
mar=c(1,1,0,0),
oma=c(3,0,0,0))
#Some plots
plot(function(x)x^2,from=-1,to=2, frame.plot=T,axes=F)
plot(function(x)x^3,from=-2,to=2, frame.plot=T,axes=F)
plot(rnorm(10), frame.plot=T,axes=F)
plot(1:10, frame.plot=T,axes=F)
# axis on last drawn plot (mfg=c(2,2)) - works
axis(side=1,line=0,outer=TRUE)
# set mfg to same value (mfg=c(2,2))
par(mfg=c(2,2))
# red axis is clipped to plot region, even with xpd?
axis(side=1,line=-.2,outer=FALSE,xpd=NA,col="red")
par(mfg=c(2,1))
axis(side=1,line=-.2,outer=FALSE,xpd=NA,col="red")
You can set :
par(xpd=NA)
to make sure that the axis is not clipped to the plotting region.

Change the size of the text in legend according to the length of the legend vector in the graph

I have to draw a 20 plots and horizontally place a legends in each plots.
I gave the following command for the first plot:
plot(x=1:4,y=1:4)
legend("bottom",legend = c("a","b","c","d"),horiz=TRUE,text.font=2,cex=0.64)
then for the second plot I tried :
plot(x=1:2,y=1:2)
legend("bottom",legend = c("a","b"),horiz=TRUE,text.font=2,cex=0.64)
But because the size of the character vector passed to legend argument are different I get the size of the legend different.
Since I have to plot so many different plots having varying sizes of legends,I would want to do it in an automated fashion.
Is there a way to do this which can fix the size of the legend in all the plots and fit it to graph size?
par(cex=.64) at the beginning should suffice
op <- par(cex=.64) # this fix the legend size for all plots
plot(x=1:4,y=1:4)
legend("bottom",legend = c("a","b","c","d"),horiz=TRUE,text.font=2) # no need to set cex anymore
plot(x=1:2,y=1:2)
legend("bottom",legend = c("a","b"),horiz=TRUE,text.font=2)
par(op) # At end of plotting, reset to previous settings

How to display all x labels in R barplot?

This is a basic question but I am unable to find an answer. I am generating about 9 barplots within one panel and each barplot has about 12 bars. I am providing all the 12 labels in my input but R is naming only alternate bars. This is obviously due to to some default setting in R which needs to be changed but I am unable to find it.
You may be able get all of the labels to appear if you use las=2 inside the plot() call. This argument and the others mentioned below are described in ?par which sets the graphical parameters for plotting devices. That rotates the text 90 degrees. Otherwise, you will need to use xaxt="n" (to suppress ticks and labels) and then put the labels in with a separate call to axis(1, at= <some numerical vector>, labels=<some character vector>).
# midpts <- barplot( ... ) # assign result to named object
axis(1, at = midpts, labels=names(DD), cex.axis=0.7) # shrinks axis labels
Another method is to first collect the midpoints and then use text() with xpd=TRUE to allow text to appear outside the plot area and srt be some angle for text rotation as named arguments to control the degree of text rotation:
text(x=midpts, y=-2, names(DD), cex=0.8, srt=45, xpd=TRUE)
The y-value needs to be chosen using the coordinates in the plotted area.
Copying a useful comment: For future readers who don't know what these arguments do: las=2 rotates the labels counterclockwise by 90 degrees. furthermore, if you need to reduce the font you can use cex.names=.5 to shrink the size down
To get rotated labels on a base R barplot, you could (like I do here) adapt one of the
examples given in the vignette of the gridBase package:
library(grid)
library(gridBase)
## Make some data with names long enough that barplot won't print them all
DD <- table(rpois(100, lambda=5))
names(DD) <- paste("long", names(DD), sep="_")
## Plot, but suppress the labels
midpts <- barplot(DD, col=rainbow(20), names.arg="")
## Use grid to add the labels
vps <- baseViewports()
pushViewport(vps$inner, vps$figure, vps$plot)
grid.text(names(DD),
x = unit(midpts, "native"), y=unit(-1, "lines"),
just="right", rot=50)
popViewport(3)
R won't label every bar if the labels are too big.
I would suggest trying to rotate the labels vertically by passing in the las=2 argument to your plotting function.
If the labels are still too large, you can try shrinking the font by using the cex.names=.5 argument.
Sample Data for plot
sample_curve <- c(2.31,2.34,2.37,2.52,2.69,2.81,2.83,2.85,2.94, 3.03, 3.21, 3.33) # create a sample curve
names(sample_curve)<-c("1 MO","2 MO","3 MO","6 MO","1 YR","2 YR","3 YR","5 YR","7 YR","10 YR","20 YR","30 YR") # label the curve
Example of plot with labels too big
barplot(sample_curve) # labels too big for the plot
Example of plot with labels rotated and small
barplot(sample_curve, las=2, cex.names=.5) # lables are rotated and smaller, so they fit
before plotting the barplot()
You can simply increase the margins with par() and your margins values (your plot has 4 margins) mar = c(v1,v2,v3,V4)
par(mar=c(10,4,4,4))
as example :
par(mar=c(10,4,4,4))
barplot(height=c(1,5,8,19,7),
names.arg=c("very long label 1","very long label 2",
"very long label 3","very long label 4",
"very long label 5"), las=2 )

Resources