Related
I am using a package called microbiomeMarker to plot a cladogram (ggtree). It was taking too long to print so I implemented the Cairo package so that the printing is faster (there's a considerable change thankfully.
cladogram<-plot_cladogram(
OTU_lefse_res,
color = c("#7570B3","#D95F02"),
only_marker = TRUE,
branch_size = 0.2, #beyond this point everything is default values
alpha = 0.2,
node_size_scale = 1,
node_size_offset = 1,
clade_label_level = 4,
clade_label_font_size = 4,
annotation_shape = 22,
annotation_shape_size = 5,
group_legend_param = list(),
marker_legend_param = list()
)
ggsave(
filename = "16S_Marker_Cladogram.png",
units = "px",
dpi = 300,
type = "cairo-png"
)
My issue is that when it gets saved, the graph is zoomed in (as far as I can figure to the bottom right corner of the legend) so I can't see the cladogram. I've also tried saving it as a pdf, changing the dpi to 900, defining the size by pixels, setting in the ggplot "coord_fixed()"... I'm at a loss, I googled the issue but I can't find anyone having a similar issue. The example data of the package works fine. I've got about 10x the amount of data to be plotted, so I expect some delay, but I don't understand why I can't get it right.
If I don't set a printing device and just do:
plot_cladogram(
OTU_lefse_res,
color = c("#7570B3","#D95F02"),
only_marker = TRUE,
branch_size = 0.2,
alpha = 0.2,
node_size_scale = 1,
node_size_offset = 1,
clade_label_level = 4,
clade_label_font_size = 4,
annotation_shape = 22,
annotation_shape_size = 5,
group_legend_param = list(),
marker_legend_param = list()
)
I don't get any output in the plot window. Any ideas of something else I can try?
I am attempting to make a chord diagram of a fairly large 18*65 table (not every cell has a value).
I have generated the image I want but the quallity of it is nothing like what is shown on the github seen below:
I figure maybe the number of cells needing to be plotted may cause problems but otherwise I am not sure why i get such a difference:
circos.par(gap.after = c(rep(2, ncol(chord_data)-1), 10, rep(2, 8-1), 5, rep(2, 10-1), 5, rep(2, 5-1), 5, rep(2, 3-1), 5, rep(2, 1), 5, rep(2, 12-1), 5, rep(2, 10-1), 5, rep(2, 6-1), 5, rep(2, 7-1), rep(2, 3-1), 10))
png(file = "antismash_by_type.png", width = 800, height = 800)
chordDiagram(chord_data,
grid.col = grid.col,
order = order,
annotationTrack = "grid",
preAllocateTracks = 1)
circos.track(track.index = 1, panel.fun = function(x, y) {
circos.text(CELL_META$xcenter, CELL_META$ylim[1], CELL_META$sector.index,
facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
}, bg.border = NA)
dev.off()
Secondly my chords do not appear to be scaling to the value of the cell which ranges from 0-100 and from what I read this is meant to occure by default but does not appear to be.
I want each rectangle to contain a number, so that the first plotted rectangle would contain : rect 1 the second rect 2 and so on, but i don't know how to insert text inside rectangles.
require(grDevices)
## set up the plot region:
plot(c(0, 250), c(0, 250), type = "n",
main = "Exercise 1: R-Tree Index Question C")
rect(0.0,0.0,40.0,35.0, , text= "transparent")
rect(10.0,210.0,45.0,230.0)
rect(170.0,50.0,240.0,150.0)
rect(75.0,110.0,125.0,125.0)
rect(50.0,130.0,65.0,160.0)
rect(15.0,140.0,30.0,150.0)
rect(100.0,50.0,130.0,90.0)
rect(150.0,40.0,155.0,60.0)
rect(52.0,80.0,75.0,90.0)
rect(62.0,65.0,85.0,75.0)
rect(20.0,75.0,25.0,80.0)
rect(30.0,40.0,50.0,80.0)
rect(102.0,155.0,113.0,217.0)
par(op)
Like the other answers mention, you can use the coordinates that you give to rect to place the text somewhere relative.
plot(c(0, 250), c(0, 250), type = "n",
main = "Exercise 1: R-Tree Index Question C")
rect(0.0,0.0,40.0,35.0)
center <- c(mean(c(0, 40)), mean(c(0, 35)))
text(center[1], center[2], labels = 'hi')
You can easily put this into a function to save yourself some typing/errors
recttext <- function(xl, yb, xr, yt, text, rectArgs = NULL, textArgs = NULL) {
center <- c(mean(c(xl, xr)), mean(c(yb, yt)))
do.call('rect', c(list(xleft = xl, ybottom = yb, xright = xr, ytop = yt), rectArgs))
do.call('text', c(list(x = center[1], y = center[2], labels = text), textArgs))
}
Use it like this
recttext(50, 0, 100, 35, 'hello',
rectArgs = list(col = 'red', lty = 'dashed'),
textArgs = list(col = 'blue', cex = 1.5))
You need to use text() as a separate graphics call.
coords <- matrix(
c(0.0,0.0,40.0,35.0,
10.0,210.0,45.0,230.0,
170.0,50.0,240.0,150.0,
75.0,110.0,125.0,125.0,
50.0,130.0,65.0,160.0,
15.0,140.0,30.0,150.0,
100.0,50.0,130.0,90.0,
150.0,40.0,155.0,60.0,
52.0,80.0,75.0,90.0,
62.0,65.0,85.0,75.0,
20.0,75.0,25.0,80.0,
30.0,40.0,50.0,80.0,
102.0,155.0,113.0,217.0),
ncol=4,byrow=TRUE)
plot(c(0, 250), c(0, 250), type = "n",
main = "Exercise 1: R-Tree Index Question C")
rfun <- function(x,i) {
do.call(rect,as.list(x))
}
apply(coords,1,rfun)
text((coords[,1]+coords[,3])/2,
(coords[,2]+coords[,4])/2,
seq(nrow(coords)))
text( (0.0+40.0)/2, (0.0+35.0)/2 , 'transparent')
where we chose x,y to be the centroid of your rectangle. You could define a function to draw the rect then place the text at its centroid.
Note: these coords are large; this will display outside your normal view. So you'll either need to zoom to see it, or scale coords to the range 0.0..1.0
By the way, read 12.2 Low-level plotting commands
I am trying to create a heatmap using the aheatmap function from the NMF package. Below are the details of my data frame:
> dim(mirs)
[1] 249 10
> dput(head(mirs))
structure(list(Ctrl.1 = c(6.16181305031523, 7.1487208026042,
5.62305791288953, 6.48859753175019, 5.86448920099041, 7.54685590953394
), Ctrl.1 = c(6.01374431772049, 6.72364369422584, 5.94212799544158,
6.49697673701072, 6.27001491471232, 7.34423932678338), Ctrl.1 = c(6.08391877575544,
6.39383949993274, 5.9014256751437, 6.25322722017054, 6.02433921913527,
7.46048761260105), Ctrl.2 = c(6.05861842019582, 7.13778005751039,
6.07807310866636, 6.27799281508687, 5.9134130919514, 7.63249818573085
), Ctrl.3 = c(6.08966189744544, 7.50580543734962, 6.22308072664994,
6.50948356694844, 5.85467671344847, 7.69872387512424), KO.1 = c(6.01642055995834,
7.40800030898938, 5.76546680318882, 6.61403760055652, 5.94451005808497,
7.24179808413933), KO.1 = c(6.14954015244869, 7.35556286637155,
5.97997384889883, 6.63097271768056, 6.00315186944306, 7.4492860653164
), KO.1 = c(5.94805813320882, 6.84281163223775, 5.80410165075893,
6.34540217272193, 5.75166634057481, 7.47062580379961), KO.2 = c(5.97334370529652,
7.41685185578274, 6.09298712573127, 6.14896460752862, 6.03396383178639,
7.41543958735736), KO.3 = c(6.23339353310102, 7.8101475680467,
5.89241431063385, 6.35967585549527, 5.87334378152986, 7.62655831252478
)), .Names = c("Ctrl.1", "Ctrl.1", "Ctrl.1", "Ctrl.2", "Ctrl.3",
"KO.1", "KO.1", "KO.1", "KO.2", "KO.3"), row.names = c(24L, 29L,
243L, 290L, 309L, 499L), class = "data.frame")
> aheatmap(x = as.matrix(mirs), scale = 'row', distfun = dist2, legend = F, fontsize = 12, cexRow = .9, cexCol = .9, main = 'miRNA Expression Profile (n=249)', filename = 'plot.pdf', width = 5, height = 10)
There are 249 rows & 10 columns in my data but I have shown only top rows using head. The column labels resize accordingly when I change the fontsize but the problem is that the row labels do not. They appear really small in the pdf no matter how much I increase the fontsize or cexRow value. Can someone suggest how to increase the size of the row labels? Attached is my plot & as you can see I have used the same values for cexRow & cexCol but the rowlabels are really small compared to col labels.
There was indeed an issue in the computed fontsize for row labels.
This has now been fixed.
See: https://github.com/renozao/NMF/issues/38
The following should give you row labels that increase together with height:
aheatmap(x = as.matrix(dat), scale = 'row', legend = F
, main = 'Heatmap', filename = 'plot.pdf'
, width = 5, height = 10)
I want to plot three plots vary close together, so they appear as one field. My data are arrays with different dimensions.
Here is some example code to display my problem:
library(lattice)
theme.novpadding = list(layout.heights = list(top.padding = 0,
main.key.padding = 0,
key.axis.padding = 0,
axis.xlab.padding = 0,
xlab.key.padding = 0,
key.sub.padding = 0,
bottom.padding = 0),
layout.widths = list(left.padding = 0,
key.ylab.padding = 0,
ylab.axis.padding = 0,
axis.key.padding = 0,
right.padding = 0),
axis.line = list(col = "transparent"))
p1 = levelplot(array(c(1:100), c(10,10)), colorkey=F, par.settings=theme.novpadding)
p2 = levelplot(array(c(1:100), c(9,9)), colorkey=F, ylab = NULL, par.settings=theme.novpadding)
p3 = levelplot(array(c(1:100), c(11,11)), ylab=NULL, par.settings=theme.novpadding)
width = 0.33
height = 1
ph = list(5, "in")
print(p1, position = c(0, 0, width, height), panel.height=ph, more=T)
print(p2, position = c(width, 0, 2*width, height), panel.height=ph, more=T)
print(p3, position = c(2*width, 0, 3*width, height),panel.height=ph, more=F)
As you see, they are spread very wide. I want them as close as possible.
I use theme.novpadding to set the margins to zero.
Is the a way to say something like "distance between plots"?
This problem is easy to solve if you structure your data into a nice data.frame. Lattice works best on data.frames. See the example bellow:
g.xy <- expand.grid(1:10, 1:10)
my.data <- data.frame(x=g.xy$Var1, y = g.xy$Var2, value1=1:100, value2 = 1:100, value3=1:100, value4=1:100)
levelplot(value1+value2+value3+value4~x+y, data=my.data, scales=list(x="free", y="free")) # free
levelplot(value1+value2+value3+value4~x+y, data=my.data, scales=list(x="same", y="same")) # same range, so panels are "touching"
You can control for the plots to appear very close together by setting the scale argument.
A trick you could use is to tweak the position argument. In stead of not letting the areas overlap, you can do just that to make them close together. For example, you can change the position arguments to:
ovr = 0.05
print(p1, position = c(0, 0, width + ovr, height), panel.height=ph, more=T)
print(p2, position = c(width - ovr, 0, 2*width+ovr, height), panel.height=ph, more=T)
print(p3, position = c(2*width - ovr, 0, 3*width, height),panel.height=ph, more=F)
You have to some tweaking with this, and I have not tested this code. But I think the general idea should work.