One must be careful when using 3D plots of any kind. It is trivial to make them:
I hope this package and vignette enables the former and deters the latter.
There are a few functions in this package:
Input data must be a numeric vector, with one value for each bar you want to plot.
The “rows” and “cols” arguments are an essential part of your plot and determine the dimensions of the grid you’re plotting in. However, your data must fit within the plotting area. i.e. 3 rows of 4 bars is 12 bars in total, so don’t attempt to plot 13 bars of data.
NOTE THAT DATA PLOTS LEFT TO RIGHT, FRONT TO BACK. You must consider this in the ordering of your input data.
Bars are set to be square (1 unit deep and 1 unit wide), and the gap size is set to be 0.2 units by default. I do not advise changing these values, but if the gap size is adjusted, bear in mind that rendering artifacts can occur if the gap is 0 and the faces of the bars touch one another and are transparent.
The “scalexy” parameter is useful for scaling the size of the bars relative to the Z height. i.e. it can be used to make your plots “skinnier” or “fatter”. Note that this scaling factor does not affect the true values of the data or the values on the Z scale.
All 3D barplots are isometric projections to minimize the potentially misleading effects of perspective. The angle the viewing position is set at is controlled by the “theta” and “phi” parameters. Experiment with these until you find something you like.
The plot size is determined by the par3d() function; in this vignette, images are captured by a different method. Again, you will have to experiment to find the right settings that make your plot and labels fully visible. I recommend resizing your plot programmatically so that it is completely reproducible. Note that only png format is currently supported by the snapshot function.
# The 4 arguments are the position (in pixels) of the left, top, right and bottom edges of the rgl viewing window
# This code leads to a plot that is 600 pixels wide and 400 pixels tall.
par3d(windowRect=c(0,50,600,450))
# Save the current rgl view
rgl.snapsnot("filename.png")
# If running multiple plots, you should close the viewing window
rgl.close()
Three components of each bar can be colored, and these colors are independent. Each should either be a vector of length 1 (which will be applied to all bars) or a vector the same length as the input data; colors will be recycled if not enough are supplied. Colors can be specified in any way that R natively understands e.g. a simple word such as “red”, an integer or a hexadecimal RGB color, like that returned by rgb() e.g. “#aaaaaa”.
Transparency of the sides of the bars can be set using the “alpha” parameter. 0 is completely transparent (i.e. a “wireframe” effect) and 1 (the default) is completely opaque. This can be useful when taller bars hide shorter bars, but if used you may want a neutral color like gray so that the topcolors are not altered by the partially transparent colored bar in front of them.
By default there is a grid pattern to make it easier to see the relative height of the bars and add labels to. However, if you want something very plain, you can turn these features on and off as you please, even removing the Z scale entirely. If you don’t like the default way they are implemented, you can explore the source code and use the axis3d() and mtext3d() functions from the rgl package.
These are 3D barplots used to display the counts (or frequency) of the 96 different combinations of somatic mutations and trinucleotide contexts seen in sequencing data. I think their first use was in Figure 1 of Exome and whole genome sequencing of esophageal adenocarcinoma identifies recurrent driver events and mutational complexity by Dulak et al, 2013. These plots are nearly identical, but the preceding and suceeding bases are in the order “ACGT”, not “TCAG”.
I have included version 2 of the COSMIC Mutational Signatures. You can use this data to
This cannot be overemphasized: your input data must be in the same order as the COSMIC data i.e. starts with C>A|G>T_AxA and ends with T>G|A>C_TxT. The full list is at the bottom of this vignette, and is stored in the “Somatic_mutation_type” column of the included “signature_probabilities.txt” file.
# Read in COSMIC signature probabilities
x=system.file("extdata", "signature_probabilities.txt", package = "barplot3d")
sigdata=read.table(x,header=TRUE,stringsAsFactors = FALSE)
# Plot signature 2 without axis labels, with Sanger colors and some transparency so we can see all bars
legoplot3d(contextdata=sigdata$Signature_2,labels=FALSE,scalexy=0.05,sixcolors="sanger",alpha=0.4)
Note that you will probably have to play with the “scalexy” parameter to get an appropriately scaled image. Also, the default colors match the Sanger signatures, but you can switch to the original Broad Institute colors if you prefer, or provide 6 arbitrary colors of your own.
# Plot signature 2 without axis labels, with Sanger colors and some transparency so we can see all bars
legoplot3d(contextdata=sigdata$Signature_8,labels=FALSE,scalexy=0.01,sixcolors="broad",alpha=0.4)
# Input data MUST be in this order
cat(sigdata$Somatic_mutation_type,sep="\n")
#> C>A|G>T_AxA
#> C>A|G>T_CxA
#> C>A|G>T_GxA
#> C>A|G>T_TxA
#> C>A|G>T_AxC
#> C>A|G>T_CxC
#> C>A|G>T_GxC
#> C>A|G>T_TxC
#> C>A|G>T_AxG
#> C>A|G>T_CxG
#> C>A|G>T_GxG
#> C>A|G>T_TxG
#> C>A|G>T_AxT
#> C>A|G>T_CxT
#> C>A|G>T_GxT
#> C>A|G>T_TxT
#> C>G|G>C_AxA
#> C>G|G>C_CxA
#> C>G|G>C_GxA
#> C>G|G>C_TxA
#> C>G|G>C_AxC
#> C>G|G>C_CxC
#> C>G|G>C_GxC
#> C>G|G>C_TxC
#> C>G|G>C_AxG
#> C>G|G>C_CxG
#> C>G|G>C_GxG
#> C>G|G>C_TxG
#> C>G|G>C_AxT
#> C>G|G>C_CxT
#> C>G|G>C_GxT
#> C>G|G>C_TxT
#> C>T|G>A_AxA
#> C>T|G>A_CxA
#> C>T|G>A_GxA
#> C>T|G>A_TxA
#> C>T|G>A_AxC
#> C>T|G>A_CxC
#> C>T|G>A_GxC
#> C>T|G>A_TxC
#> C>T|G>A_AxG
#> C>T|G>A_CxG
#> C>T|G>A_GxG
#> C>T|G>A_TxG
#> C>T|G>A_AxT
#> C>T|G>A_CxT
#> C>T|G>A_GxT
#> C>T|G>A_TxT
#> T>A|A>T_AxA
#> T>A|A>T_CxA
#> T>A|A>T_GxA
#> T>A|A>T_TxA
#> T>A|A>T_AxC
#> T>A|A>T_CxC
#> T>A|A>T_GxC
#> T>A|A>T_TxC
#> T>A|A>T_AxG
#> T>A|A>T_CxG
#> T>A|A>T_GxG
#> T>A|A>T_TxG
#> T>A|A>T_AxT
#> T>A|A>T_CxT
#> T>A|A>T_GxT
#> T>A|A>T_TxT
#> T>C|A>G_AxA
#> T>C|A>G_CxA
#> T>C|A>G_GxA
#> T>C|A>G_TxA
#> T>C|A>G_AxC
#> T>C|A>G_CxC
#> T>C|A>G_GxC
#> T>C|A>G_TxC
#> T>C|A>G_AxG
#> T>C|A>G_CxG
#> T>C|A>G_GxG
#> T>C|A>G_TxG
#> T>C|A>G_AxT
#> T>C|A>G_CxT
#> T>C|A>G_GxT
#> T>C|A>G_TxT
#> T>G|A>C_AxA
#> T>G|A>C_CxA
#> T>G|A>C_GxA
#> T>G|A>C_TxA
#> T>G|A>C_AxC
#> T>G|A>C_CxC
#> T>G|A>C_GxC
#> T>G|A>C_TxC
#> T>G|A>C_AxG
#> T>G|A>C_CxG
#> T>G|A>C_GxG
#> T>G|A>C_TxG
#> T>G|A>C_AxT
#> T>G|A>C_CxT
#> T>G|A>C_GxT
#> T>G|A>C_TxT