R Plot two graphs; One large, one small - r

I want to make a figure similar to this
See how the bottom portion is tiny... how do I do that?
I'm ok in ggplots2 so give me your expertise please.
I do not need to plot 2 values on the larger one. Essentially, I know how to generate everything I want from this figure, except how to make a tiny plot under a larger one (sans photoshop)
I have data.frames that contain the transcript information in the figure at the bottom, I'm only interested in one gene. To plot the genes you would do something like this
plot(transcript, type="l", lwd=2)
points(exons, type="l", lwd=3, col="blue")
points(utrExons, type="l", lwd=3)
To plot the large figure it would look like this
plot(genetic.variant, pch=16)
An exhaustive internet search turned into bupkis, how do you make two figures in the same plotting area with one of them being much smaller than the other?

With base graphics you can do something like this
dd<-data.frame(x=1:100, y1=runif(100), y2=cumsum(rnorm(100)))
layout(matrix(1:2, ncol=1), heights=c(3,1))
par(mar=c(0,3,3,2))
plot(y1~x,dd, xaxt="n", xlab="")
par(mar=c(3,3,0,2))
plot(y2~x,dd)

You can use layout
layout(c(1,2),widths=c(5,1),heights=c(5,1),T)
par(mar=c(1,1,1,1)
and just change the heights depending on your preference

Related

How to plot a picture in R and change its background color

My goal is to plot with R a colored map of the human body, and will use here the simplified example of a smiley. I see two options but am stuck with both:
1) Extracting the different areas of the body using photoshop, and then plotting them on the top of each other:
R
link = "http://images.clipartpanda.com/clipart-smiley-face-9czEnApcE.jpeg"
download.file(link,basename(link))
jj <- readJPEG("clipart-smiley-face-9czEnApcE.jpeg",native=TRUE)
plot(1, type="n", axes=F, xlab="", ylab="")
rasterImage(jj,0.7,0.6,1,1)
I look for a way to do something like
rasterImage(jj,0.7,0.6,1,1, col="yellow")
But rasterImage works only with opaque pictures :/
2) Defining a polygon by interactively clicking on the picture, save that polygon to plot it later on the top of the original pic. That way I could simply create a map of the human body.
But most maps are for countries and so rely on available geographical data.
Is there a way to "draw" in R lines and define polygons in an easy way?

R: Resize 2 x 2 plot output

I have 4 maps to plot and would like to plot them in a single plot area so I use the code
par(mfrow=c(2,2), bty="n")
However, the result is lots of useless blank space around my maps (which become also too small).
The image below shows how much space is taken up by each map (blue rectangle) relative to the plot area.
Is it possible to go from the current situation (cf. 2 x 2 plot fit) to the desired situation (cf. Desired better fit)?
I tried changing width and height parameters (dev.new(width=x, height=y)) but with no luck.
I would suggest using the layout function, though using par is fine too. I give a simple example below, in which you can adjust par(mar=c()) settings for each individual plot, bringing them closer together. layout allows you to adjust relative heights of plots with the height parameter, which might be useful when trying to get panel plots to be all the same height, when you have the x-axis only for the lower tier plots.
y=runif(100)
x=runif(100)
layout(matrix(c(1,2,3,4), byrow=TRUE, ncol=2,nrow=2))
par(mar=c(3,3,0.5,0.5))
plot(y,x, xaxt='n')
par(mar=c(3,3,0.5,0.5))
plot(y,x, xaxt='n')
par(mar=c(3,3,0.5,0.5))
plot(y,x)
par(mar=c(3,3,0.5,0.5))
plot(y,x, yaxt='n')

R how to make legend position independent from graph size

Here is my code; basically I am putting four graphs on the same plot device and putting a legend on each. [edit: I am working with RStudio]
dev.new()
par(mfrow=c(2,2), oma=c(0,0,2,0))
#plot1
plot(parameters...)
par(new=TRUE)
plot(parameters, col="red")
legend("bottomright", c("seed match", "background"), bty="n", lty=c(1,1),
col=c("red","black"), cex=0.8, inset=0)
#plot2
plot(parameters...)
par(new=TRUE)
plot(parameters..., col="red")
legend("bottomright", c("seed match", "background"), bty="n", lty=c(1,1),
col=c("red","black"), cex=0.8,inset=0)
#etc. same for plot2 and plot 3
title("bla bla bla", outer=TRUE)
I have two issues with this.
(1) even though I specified "bottomright", the legend doesn't seem to be aligned to the bottom right, the wider I resize the graph horizontally, the more space there is between the legend and the right of the graph.
(2) the amount of space the legend occupies is inadequate. I tried modifying cex= but that only takes care of font size, the overall space occupied by the legend remains, meaning that the smaller the font, the bigger the space between lines. I would like the legend to be a little less "spread out".
Illustration
This looks sort of OK, although I would like to decrease the space between lines inside the legend:
But when I resize horizontally it doesn't. I would like to tether the legend to the right of the graph.
(1):
As your graphs are all scaled the same way, you could use x and y coordinates to position the legend, not the key words. e.g.:
legend(x = 0.25, y = 35, c("seed match", "background"), bty="n", lty=c(1,1), col=c("red","black"), cex=0.8, inset=0)
(2):
I don't know if there exists a way to manipulate line spacing via legend(), I didn't find one. I always switch to manual generation of the legend via mtext(), abline() and such when the legend has to look really pretty. It is more work but you got control over every aspect of your legend.
One last comment: I guess you want your graph to like nice not on your screen but on some sort of paper or presentation. I always generate graphs with devices like cairo_ps(), svg() or jpeg() (jpeg only on rare occasions because it is raster, not vector-based). These functions give you more control about your graphs than exporting the R Graphics Device. But the way a graph looks changes with the device, each one needs to be configured separately. Better do it only for the one you are going to use in the end.
I hope this helps
Instead of using "bottomright", you could use legend() twice, for each legend element with position values you choose such as
legend(x1,y1,c("seed match"), bty="n", lty=1, col="red", cex=0.8)
for the first one. This way you can choose their position individually and therefore control the spacing between them. I think this solve your two issues.

Do R plots have handles?

Do plots in R have handles? For example, if I were to use something like this:
plot(plotData[,1], plotData[,2], type='l', col='red', lty=2, xlab='x',
ylab='y', main='sample plot')
would I be able to change anything in this plot later like the color, or the x-axis label, or the x-axis range, etc.? Or do I have the plot this all over again?
Thanks!
Base R does not have handles in the sense that you are asking. Although you can modify some aspects of the plot after you've plotted it, much better suited to the needs in question would be to use ggplot
You can save the output to an object and append as needed.
You can also use last_plot()
Have a look at
http://www.cookbook-r.com/Graphs/ and http://docs.ggplot2.org/current/

R - Scatter plots, how to plot points in differnt lines to overlapping?

I want to plot several lists of points, each list has distance (decimal) and error_no (1-8). So far I am using the following:
plot(b1$dist1, b1$e1, col="blue",type="p", pch=20, cex=.5)
points(b1$dist2, b1$e2, col="blue", pch=22)
to add them both to the same plot. (I will add legends, etc later on).
The problem I have is that points overlap, and even when changing the character using for plotting, it covers up previous points. Since I am planning on plotting a lot more than just 2 this will be a big problem.
I found some ways in:
http://www.rensenieuwenhuis.nl/r-sessions-13-overlapping-data-points/
But I would rather do something that would space the points along the y axis, one way would be to add .1, then .2, and so on, but I was wondering if there was any package to do that for me.
Cheers
M
ps: if I missed something, please let me know.
As noted in the very first point in the link you posted, jitter will slightly move all your points. If you just want to move the points on the y-axis:
plot(b1$dist1, b1$e1, col="blue",type="p", pch=20, cex=.5)
points(b1$dist2, jitter(b1$e2), col="blue", pch=22)
Depends a lot on what information you wish to impart to the reader of your chart. A common solution is to use the transparency quality of R's color specification. Instead of calling a color "blue" for example, set the color to #0000FF44 (Apologies if I just set it to red or green) The final two bytes define the transparency, from 00 to FF, so overlapping data points will appear darker than standalone points.
Look at the spread.labs function in the TeachingDemos package, particularly the example. It may be that you can use that function to create your plot (the examples deal with labels, but could just as easily be applied to the points themselves). The key is that you will need to find the new locations based on the combined data, then plot. If the function as is does not do what you want, you could still look at the code and use the ideas to spread out your points.
Another approach would be to restructure your data and use the ggplot2 package with "dodging". Other approaches rather than using points several times would be the matplot function, using the col argument to plot with a vector, or lattice or ggplot2 plots. You will probably need to restructure the data for any of these.

Resources