Odd Number plots using levelplot and rasterVis - layout

I'm using the rasterVis package and the levelplot function to plot seven rasters on a single plot.
Here is the layout I'm going for:
correct layout
I've achieved this using the following code:
png("E:/all_files/production/plots/for_final/hist_vis_split2.png",
width=6, height=9, units="in", res=72)
layout(matrix(c(1,1,2,3,4,5,6,7), 4, 2, byrow = T))
print(maurer+layer(sp.lines(sr)), split=c(2,1,3,4), more=TRUE)
print(nar.ccsm+layer(sp.lines(sr)), split=c(1,2,3,4), more=TRUE)
print(nar.gfdl+layer(sp.lines(sr)), split=c(3,2,3,4), more=TRUE)
print(bcsd.ccsm+layer(sp.lines(sr)), split=c(1,3,3,4), more=TRUE)
print(bcsd.gfdl+layer(sp.lines(sr)), split=c(3,3,3,4), more=TRUE)
print(bcca.ccsm+layer(sp.lines(sr)), split=c(1,4,3,4), more=TRUE)
print(bcca.gfdl+layer(sp.lines(sr)), split=c(3,4,3,4))
dev.off()
Besides being clunky and lacking control, this is still missing a main title and a single common colorkey for the entire image.
I would prefer to use the levelplot command. Below is the code I've used to plot all seven rasters in a single levelplot with a single colorkey. Unfortunately this does not have the correct layout:
incorrect layout
crop.stack <- stack(maurer, bcsd.ccsm.crop, bcsd.gfdl.crop, bcca.ccsm.crop,
bcca.gfdl.crop, nar.ccsm.crop, nar.gfdl.crop)
plot.names <- c("Maurer", "BCSD CCSM", "BCSD GFDL", "BCCA CCSM",
"BCCA GFDL", "NARCCAP CCSM", "NARCCAP GFDL")
png("E:/all_files/production/plots/for_final/hist_vis.png",
width=6, height=9, units="in", res=72)
hist <- levelplot(crop.stack, main="Historical Average Production Days",
col.regions=cols,
names.attr=plot.names,
scales=list(draw=F),
layout=c(2,4))
hist + layer(sp.lines(sr))
dev.off()
The solution here is close, but does not deal with and odd number of plots. How can I achieve the desired layout within the levelplot command?

Related

How can I take the outer product of string vectors in J?

I'm trying to replicate the outer product notation in APL:
∘.,⍨ 'x1' 'y1' 'z1' 'x2' 'y2' 'z2' 'x3' 'y3' 'z3'
which yields
x1x1 x1y1 x1z1 x1x2 x1y2 x1z2 x1x3 x1y3 x1z3
y1x1 y1y1 y1z1 y1x2 y1y2 y1z2 y1x3 y1y3 y1z3
z1x1 z1y1 z1z1 z1x2 z1y2 z1z2 z1x3 z1y3 z1z3
x2x1 x2y1 x2z1 x2x2 x2y2 x2z2 x2x3 x2y3 x2z3
y2x1 y2y1 y2z1 y2x2 y2y2 y2z2 y2x3 y2y3 y2z3
z2x1 z2y1 z2z1 z2x2 z2y2 z2z2 z2x3 z2y3 z2z3
x3x1 x3y1 x3z1 x3x2 x3y2 x3z2 x3x3 x3y3 x3z3
y3x1 y3y1 y3z1 y3x2 y3y2 y3z2 y3x3 y3y3 y3z3
z3x1 z3y1 z3z1 z3x2 z3y2 z3z2 z3x3 z3y3 z3z3
But I can't figure out how to do something similar in J. I found this Cartesian product in J post that I thought would be similar enough, but I just can't seem to translate it to an array of strings from an array of numbers.
Adapting Dan Bron's answer therein and applying it to a simpler example
6 6 $ , > { 2 # < 'abc'
gives
aaabac
babbbc
cacbcc
aaabac
babbbc
cacbcc
which is almost what I want, but I don't know how to generalize it to use 2-letter (or more) strings instead of single ones in a similar fashion. I also don't know how to format those results with spaces between the pairs like the APL output, so it may not be the right path either.
Similarly, I tried adapting Michael Berry's answer from that thread to get
9 36 $ ,,"1/ ~ 9 2 $ 'x1y1z1x2y2z2x3y3z3'
which gives
x1x1x1y1x1z1x1x2x1y2x1z2x1x3x1y3x1z3
y1x1y1y1y1z1y1x2y1y2y1z2y1x3y1y3y1z3
z1x1z1y1z1z1z1x2z1y2z1z2z1x3z1y3z1z3
x2x1x2y1x2z1x2x2x2y2x2z2x2x3x2y3x2z3
y2x1y2y1y2z1y2x2y2y2y2z2y2x3y2y3y2z3
z2x1z2y1z2z1z2x2z2y2z2z2z2x3z2y3z2z3
x3x1x3y1x3z1x3x2x3y2x3z2x3x3x3y3x3z3
y3x1y3y1y3z1y3x2y3y2y3z2y3x3y3y3y3z3
z3x1z3y1z3z1z3x2z3y2z3z2z3x3z3y3z3z3
Again, this is almost what I want, and this one handled the multiple characters, but there are still no spaces between them and the command is getting farther from the simplicity of the APL version.
I can get the same results a bit more cleanly with ravel items
,. ,"1/ ~ 9 2 $ 'x1y1z1x2y2z2x3y3z3'
I've been going through the J primer and exploring parts that look relevant in the dictionary, but I'm still very new, so I apologize if this is a dumb question. I feel like the rank conjunction operator should be able to help me here, but I had a hard time following its explanation in the primer. I played with ": to try to format the strings to have trailing spaces, but I also couldn't figure that out. The fact that this was so easy in APL also makes me think I'm doing something very wrong in J to be having this much trouble.
After reading more of the primer I got something that looks like what I want with
,. 9 1 $ ' ' ,."2 ,"1/~ [ ;._2 'x1 y1 z1 x2 y2 z2 x3 y3 z3 '
but this is still way more complicated than the APL version, so I'm still hoping there is an actually elegant and concise way to do this.
I think that the only thing that I can add to the things that you have already pointed out is that to keep a string separate into components you would need to box.
<#,"1/~ 9 2 $ 'x1y1z1x2y2z2x3y3z3'
+----+----+----+----+----+----+----+----+----+
|x1x1|x1y1|x1z1|x1x2|x1y2|x1z2|x1x3|x1y3|x1z3|
+----+----+----+----+----+----+----+----+----+
|y1x1|y1y1|y1z1|y1x2|y1y2|y1z2|y1x3|y1y3|y1z3|
+----+----+----+----+----+----+----+----+----+
|z1x1|z1y1|z1z1|z1x2|z1y2|z1z2|z1x3|z1y3|z1z3|
+----+----+----+----+----+----+----+----+----+
|x2x1|x2y1|x2z1|x2x2|x2y2|x2z2|x2x3|x2y3|x2z3|
+----+----+----+----+----+----+----+----+----+
|y2x1|y2y1|y2z1|y2x2|y2y2|y2z2|y2x3|y2y3|y2z3|
+----+----+----+----+----+----+----+----+----+
|z2x1|z2y1|z2z1|z2x2|z2y2|z2z2|z2x3|z2y3|z2z3|
+----+----+----+----+----+----+----+----+----+
|x3x1|x3y1|x3z1|x3x2|x3y2|x3z2|x3x3|x3y3|x3z3|
+----+----+----+----+----+----+----+----+----+
|y3x1|y3y1|y3z1|y3x2|y3y2|y3z2|y3x3|y3y3|y3z3|
+----+----+----+----+----+----+----+----+----+
|z3x1|z3y1|z3z1|z3x2|z3y2|z3z2|z3x3|z3y3|z3z3|
+----+----+----+----+----+----+----+----+----+
If you want to get rid of the boxes and instead insert spaces then you are not really going to have the character items separately, you will have long strings with the spaces as part of the result.
And it is a very good question because it requires you to understand the fact that character strings in J are vectors. I suppose that technically what you are looking for is this which results in a 9 9 4 shape, but it won't look the way that you expect.
,"1/~ 9 2 $ 'x1y1z1x2y2z2x3y3z3'
x1x1
x1y1
x1z1
x1x2
x1y2
x1z2
x1x3
x1y3
x1z3
y1x1
y1y1
y1z1
y1x2
y1y2
y1z2
y1x3
y1y3
y1z3
z1x1
z1y1
z1z1
z1x2
z1y2
z1z2
z1x3
z1y3
z1z3
x2x1
x2y1
x2z1
x2x2
x2y2
x2z2
x2x3
x2y3
x2z3
y2x1
y2y1
y2z1
y2x2
y2y2
y2z2
y2x3
y2y3
y2z3
z2x1
z2y1
z2z1
z2x2
z2y2
z2z2
z2x3
z2y3
z2z3
x3x1
x3y1
x3z1
x3x2
x3y2
x3z2
x3x3
x3y3
x3z3
y3x1
y3y1
y3z1
y3x2
y3y2
y3z2
y3x3
y3y3
y3z3
z3x1
z3y1
z3z1
z3x2
z3y2
z3z2
z3x3
z3y3
z3z3
$ ,"1/~ 9 2 $ 'x1y1z1x2y2z2x3y3z3'
9 9 4
You could also take the boxes and convert them to symbols, which might be closer to what you want, although they do have the backtick indicator as part of their representation.
s:#<#,"1/~ 9 2 $ 'x1y1z1x2y2z2x3y3z3'
`x1x1 `x1y1 `x1z1 `x1x2 `x1y2 `x1z2 `x1x3 `x1y3 `x1z3
`y1x1 `y1y1 `y1z1 `y1x2 `y1y2 `y1z2 `y1x3 `y1y3 `y1z3
`z1x1 `z1y1 `z1z1 `z1x2 `z1y2 `z1z2 `z1x3 `z1y3 `z1z3
`x2x1 `x2y1 `x2z1 `x2x2 `x2y2 `x2z2 `x2x3 `x2y3 `x2z3
`y2x1 `y2y1 `y2z1 `y2x2 `y2y2 `y2z2 `y2x3 `y2y3 `y2z3
`z2x1 `z2y1 `z2z1 `z2x2 `z2y2 `z2z2 `z2x3 `z2y3 `z2z3
`x3x1 `x3y1 `x3z1 `x3x2 `x3y2 `x3z2 `x3x3 `x3y3 `x3z3
`y3x1 `y3y1 `y3z1 `y3x2 `y3y2 `y3z2 `y3x3 `y3y3 `y3z3
`z3x1 `z3y1 `z3z1 `z3x2 `z3y2 `z3z2 `z3x3 `z3y3 `z3z3
I'd say the closest direct analogue of the APL expresion is to keep each string boxed:
,&.>/~ 'x1';'y1';'z1';'x2';'y2';'z2';'x3';'y3';'z3'
┌────┬────┬────┬────┬────┬────┬────┬────┬────┐
│x1x1│x1y1│x1z1│x1x2│x1y2│x1z2│x1x3│x1y3│x1z3│
├────┼────┼────┼────┼────┼────┼────┼────┼────┤
│y1x1│y1y1│y1z1│y1x2│y1y2│y1z2│y1x3│y1y3│y1z3│
├────┼────┼────┼────┼────┼────┼────┼────┼────┤
│z1x1│z1y1│z1z1│z1x2│z1y2│z1z2│z1x3│z1y3│z1z3│
├────┼────┼────┼────┼────┼────┼────┼────┼────┤
│x2x1│x2y1│x2z1│x2x2│x2y2│x2z2│x2x3│x2y3│x2z3│
├────┼────┼────┼────┼────┼────┼────┼────┼────┤
│y2x1│y2y1│y2z1│y2x2│y2y2│y2z2│y2x3│y2y3│y2z3│
├────┼────┼────┼────┼────┼────┼────┼────┼────┤
│z2x1│z2y1│z2z1│z2x2│z2y2│z2z2│z2x3│z2y3│z2z3│
├────┼────┼────┼────┼────┼────┼────┼────┼────┤
│x3x1│x3y1│x3z1│x3x2│x3y2│x3z2│x3x3│x3y3│x3z3│
├────┼────┼────┼────┼────┼────┼────┼────┼────┤
│y3x1│y3y1│y3z1│y3x2│y3y2│y3z2│y3x3│y3y3│y3z3│
├────┼────┼────┼────┼────┼────┼────┼────┼────┤
│z3x1│z3y1│z3z1│z3x2│z3y2│z3z2│z3x3│z3y3│z3z3│
└────┴────┴────┴────┴────┴────┴────┴────┴────┘

Deriving boolean expressions from hand drawn logic gate diagrams with python OpenCv

Using tensorflow I identified all the gates, letters and nodes.
When identifying all above components, it draws a rectangle box around each component.
Therefore, in the following array it contains list of all the components detected. Each list is in the following order.
Name of component
X, Y coordinates of top left corner of rectangle
X, Y coordinates of right bottom of rectangle
Nodes (Black Points) are used to indicate a bridge over a line without crossing.
Array of all above components.
labels =[['NODE',(1002.9702758789062, 896.4686675071716), (1220.212585389614, 1067.1142654418945)], ['NODE',(1032.444071739912, 635.7160077095032),(1211.6839590370655, 763.4382424354553)],['M', (57.093908578157425,607.6229677200317),(311.9765570014715,833.807623386383)],['NODE', (344.5295810997486, 806.3690414428711), (501.8982524871826, 930.6454839706421)], ['Z', (21.986433800309896, 1327.9791088104248), (266.36098374426365, 1565.158670425415)], ['OR', (476.0066536962986, 574.401759147644), (918.3125713765621, 1177.1423168182373)], ['NODE', (333.50814148783684, 1058.0092916488647), (497.6142471432686, 1202.9034795761108)], ['K', (37.06201596558094, 870.0414619445801), (311.77860628068447, 1105.8665227890015)], ['AND', (665.9987451732159, 1227.940999031067), (1062.7052736580372, 1594.6843948364258)],['AND', (1373.9987451732159, 204.940999031067), (1703.7052736580372, 612.6843948364258)], ['NOT', (694.2882044911385, 260.5083291530609), (1027.812717139721, 450.35294365882874)], ['XOR', (2027.6711627840996, 593.0362477302551), (2457.9011510014534, 1093.9836854934692)], ['J', (85.69029207900167, 253.8458535671234), (334.48535946011543, 456.5887498855591)], ['OUTPUT', (2657.3825285434723, 670.8418045043945), (2929.8974316120148, 975.4852895736694)]]
Then, using line detection algorithm I identified all the 17 lines connecting each component.
All above 17 lines take as a list of arrays, and those lines are not in a correct order and each line has 2 end points.
lines = [[(60, 1502), (787, 1467)], [(125, 1031), (691, 988)], [(128, 772), (685, 758)], [(131, 336),(709,347)], [(927,350),(1455, 348)], [(400, 1361), (792, 1369)], [(834, 843), (2343, 939)], [(915, 1430), (1119, 1424)], [(1125, 468), (1453, 470)], [(1587, 399), (1911, 405)], [(1884, 755), (2245, 814)],[(2372, 831), (2918, 859)], [(1891, 397), (1901, 767)], [(1138, 457), (1128, 738)], [(441, 738), (421, 903)], [(1125, 946), (1101, 1437)], [(420, 1098), (408, 1373)]]
When connecting those lines, it is must to consider following scenario.
It means nodes are used to indicate a bridge without crossing lines.
M is an input to the AND gate and (M.Z) is an input to the other AND gate.
So how can I generate the following Boolean Expression using above 2 arrays and above scenario? This should be a function that works for all logic gates.
It can be assumed that image is always going to read from left to right.

How to draw a horizontal line at the large y-axis integer?

For the following data.dat file:
08:01:59 451206975237005878
08:04:07 451207335040839108
08:05:56 451207643872368805
08:07:49 451207961547842270
08:09:56 451208317883903787
08:10:12 451208364811411904
08:14:09 451209030026853864
08:16:19 451209395116787156
08:17:14 451209552481002386
08:20:22 451210080432357203
08:25:36 451210963309583903
08:30:23 451211772783766177
08:34:04 451212394854723707
08:35:53 451212702239472024
08:48:46 451214876715294857
08:49:56 451215072475511660
08:51:24 451215321890488523
08:52:39 451215533925588479
08:52:42 451215542324801784
08:54:30 451215845971562410
08:55:08 451215951262906948
08:58:30 451216519498960432
I'd like to draw a horizontal line at the specific level (e.g. 451211772783766177). However, the number is too large to process.
Here is my attempt (based on this post):
$ gnuplot -p -e 'set arrow from 451211772783766177 to 451211772783766177; plot "data.dat" using 2 with lines'
which gives the following error:
line 0: warning: integer overflow; changing to floating point
How I should proceed?
I would treat your large number as a constant function, and plot it right after your data. Also, writing it on a exponential notation X.XE+YY = X.X times 10 to the +YY power (more info on format specifiers here) also takes care of the error:
plot "data.dat" using 2 with lines, 4.51211772783766177E17 with lines
Let me know if this works!

How to estimate camera pose according to a projective transformation matrix of two consecutive frames?

I'm working on the kitti visual odometry dataset. I use projective transformation to register two 2D consecutive frames(see projective transformation example here
). I want to know how this 3*3 projective transformation matrix is related to the ground truth poses provided by the kitti dataset.
This dataset gives the ground truth poses (trajectory) for the sequences, which is described below:
Folder 'poses':
The folder 'poses' contains the ground truth poses (trajectory) for the
first 11 sequences. This information can be used for training/tuning your
method. Each file xx.txt contains a N x 12 table, where N is the number of
frames of this sequence. Row i represents the i'th pose of the left camera
coordinate system (i.e., z pointing forwards) via a 3x4 transformation
matrix. The matrices are stored in row aligned order (the first entries
correspond to the first row), and take a point in the i'th coordinate
system and project it into the first (=0th) coordinate system. Hence, the
translational part (3x1 vector of column 4) corresponds to the pose of the
left camera coordinate system in the i'th frame with respect to the first
(=0th) frame. Your submission results must be provided using the same data
format.
Some samples of the given groud-truth poses:
1.000000e+00 9.043680e-12 2.326809e-11 5.551115e-17 9.043683e-12 1.000000e+00 2.392370e-10 3.330669e-16 2.326810e-11 2.392370e-10 9.999999e-01 -4.440892e-16
9.999978e-01 5.272628e-04 -2.066935e-03 -4.690294e-02 -5.296506e-04 9.999992e-01 -1.154865e-03 -2.839928e-02 2.066324e-03 1.155958e-03 9.999971e-01 8.586941e-01
9.999910e-01 1.048972e-03 -4.131348e-03 -9.374345e-02 -1.058514e-03 9.999968e-01 -2.308104e-03 -5.676064e-02 4.128913e-03 2.312456e-03 9.999887e-01 1.716275e+00
9.999796e-01 1.566466e-03 -6.198571e-03 -1.406429e-01 -1.587952e-03 9.999927e-01 -3.462706e-03 -8.515762e-02 6.193102e-03 3.472479e-03 9.999747e-01 2.574964e+00
9.999637e-01 2.078471e-03 -8.263498e-03 -1.874858e-01 -2.116664e-03 9.999871e-01 -4.615826e-03 -1.135202e-01 8.253797e-03 4.633149e-03 9.999551e-01 3.432648e+00
9.999433e-01 2.586172e-03 -1.033094e-02 -2.343818e-01 -2.645881e-03 9.999798e-01 -5.770163e-03 -1.419150e-01 1.031581e-02 5.797170e-03 9.999299e-01 4.291335e+00
9.999184e-01 3.088363e-03 -1.239599e-02 -2.812195e-01 -3.174350e-03 9.999710e-01 -6.922975e-03 -1.702743e-01 1.237425e-02 6.961759e-03 9.998991e-01 5.148987e+00
9.998890e-01 3.586305e-03 -1.446384e-02 -3.281178e-01 -3.703403e-03 9.999605e-01 -8.077186e-03 -1.986703e-01 1.443430e-02 8.129853e-03 9.998627e-01 6.007777e+00
9.998551e-01 4.078705e-03 -1.652913e-02 -3.749547e-01 -4.231669e-03 9.999484e-01 -9.229794e-03 -2.270290e-01 1.649063e-02 9.298401e-03 9.998207e-01 6.865477e+00
9.998167e-01 4.566671e-03 -1.859652e-02 -4.218367e-01 -4.760342e-03 9.999347e-01 -1.038342e-02 -2.554151e-01 1.854788e-02 1.047004e-02 9.997731e-01 7.724036e+00
9.997738e-01 5.049868e-03 -2.066463e-02 -4.687329e-01 -5.289072e-03 9.999194e-01 -1.153730e-02 -2.838096e-01 2.060470e-02 1.164399e-02 9.997198e-01 8.582886e+00
9.997264e-01 5.527315e-03 -2.272922e-02 -5.155474e-01 -5.816781e-03 9.999025e-01 -1.268908e-02 -3.121547e-01 2.265686e-02 1.281782e-02 9.996611e-01 9.440275e+00
9.996745e-01 6.000540e-03 -2.479692e-02 -5.624310e-01 -6.345160e-03 9.998840e-01 -1.384246e-02 -3.405416e-01 2.471098e-02 1.399530e-02 9.995966e-01 1.029896e+01
9.996182e-01 6.468772e-03 -2.686440e-02 -6.093087e-01 -6.873365e-03 9.998639e-01 -1.499561e-02 -3.689250e-01 2.676374e-02 1.517453e-02 9.995266e-01 1.115757e+01
9.995562e-01 7.058450e-03 -2.894213e-02 -6.562052e-01 -7.530449e-03 9.998399e-01 -1.623192e-02 -3.973964e-01 2.882292e-02 1.644266e-02 9.994492e-01 1.201541e+01
9.995095e-01 5.595311e-03 -3.081450e-02 -7.018788e-01 -6.093682e-03 9.998517e-01 -1.610315e-02 -4.239119e-01 3.071983e-02 1.628303e-02 9.993953e-01 1.286965e+01
The common name for your "projective transformation" is homography. In a calibrated setup (i.e. if you know your camera's field of view or, equivalently, its focal length) a homography can be decomposed into 3D rotation and translation, the latter only up to scale. The decomposition algorithm additionally produces the normal to the 3D plane inducting the homography. The algorithm has up to 4 solutions, of which only one is feasible when you apply additional constraints, such as that the matched image points triangulate in front of the camera, and that the general direction of the translation match a known prior.
More information about the method is in a well-known paper by Malis and Vargas. There is an implementation in OpenCV, under the name decomposeHomographyMat.

R simplify heatmap to pdf

I want to plot a simplified heatmap that is not so difficult to edit with the scalar vector graphics program I am using (inkscape). The original heatmap as produced below contains lots of rectangles, and I wonder if they could be merged together in the different sectors to simplify the output pdf file:
nentries=100000
ci=rainbow(nentries)
set.seed=1
mean=10
## Generate some data (4 factors)
i = data.frame(
a=round(abs(rnorm(nentries,mean-2))),
b=round(abs(rnorm(nentries,mean-1))),
c=round(abs(rnorm(nentries,mean+1))),
d=round(abs(rnorm(nentries,mean+2)))
)
minvalue = 10
# Discretise values to 1 or 0
m0 = matrix(as.numeric(i>minvalue),nrow=nrow(i))
# Remove rows with all zeros
m = m0[rowSums(m0)>0,]
# Reorder with 1,1,1,1 on top
ms =m[order(as.vector(m %*% matrix(2^((ncol(m)-1):0),ncol=1)), decreasing=TRUE),]
rowci = rainbow(nrow(ms))
colci = rainbow(ncol(ms))
colnames(ms)=LETTERS[1:4]
limits=c(which(!duplicated(ms)),nrow(ms))
l=length(limits)
toname=round((limits[-l]+ limits[-1])/2)
freq=(limits[-1]-limits[-l])/nrow(ms)
rn=rep("", nrow(ms))
for(i in toname) rn[i]=paste(colnames(ms)[which(ms[i,]==1)],collapse="")
rn[toname]=paste(rn[toname], ": ", sprintf( "%.5f", freq ), "%")
heatmap(ms,
Rowv=NA,
labRow=rn,
keep.dendro = FALSE,
col=c("black","red"),
RowSideColors=rowci,
ColSideColors=colci,
)
dev.copy2pdf(file="/tmp/file.pdf")
Why don't you try RSvgDevice? Using it you could save your image as svg file, which is much convenient to Inkscape than pdf
I use the Cairo package for producing svg. It's incredibly easy. Here is a much simpler plot than the one you have in your example:
require(Cairo)
CairoSVG(file = "tmp.svg", width = 6, height = 6)
plot(1:10)
dev.off()
Upon opening in Inkscape, you can ungroup the elements and edit as you like.
Example (point moved, swirl added):
I don't think we (the internet) are being clear enough on this one.
Let me just start off with a successful export example
png("heatmap.png") #Ruby dev's think of this as kind of like opening a `File.open("asdfsd") do |f|` block
heatmap(sample_matrix, Rowv=NA, Colv=NA, col=terrain.colors(256), scale="column", margins=c(5,10))
dev.off()
The dev.off() bit, in my mind, reminds me of an end call to a ruby block or method, in that, the last line of the "nested" or enclosed (between png() and dev.off()) code's output is what gets dumped into the png file.
For example, if you ran this code:
png("heatmap4.png")
heatmap(sample_matrix, Rowv=NA, Colv=NA, col=terrain.colors(32), scale="column", margins=c(5,15))
heatmap(sample_matrix, Rowv=NA, Colv=NA, col=greenred(32), scale="column", margins=c(5,15))
dev.off()
it would output the 2nd (greenred color scheme, I just tested it) heatmap to the heatmap4.png file, just like how a ruby method returns its last line by default

Resources