R figure being cropped - r
Here's a bit of a basic question, you'd think R would automate this always. I'm making a heatmap (basic stuff, png() into heatmap.2() into dev.off()), and my row labels get cleaved off on the right hand side, along with a tiny part of the dendrogram on the left:
Fiddling with the margins manually would eventually lead to a sensible output, but the problem is that this is part of an automated pipeline with biologist users in mind. Surely there's some automated way to do this, right? I mean, in RGui on OSX, a quick reshape of the figure window fixes the layout automatically, so it has to be possible. Thanks, and sorry to bother you.
EDIT: Procedure to reproduce this visualisation:
Input data:
Time,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48
CATMA1A23000,0.21129,0.48322,0.54234,0.93714,0.51816,0.11103,0.38304,0.97183,0.61381,-0.13775,0.32575,0.85221,0.1921,1.8692,0.4117,0.51977,0.74019,0.98932,0.023536,0.8849,0.75141,0.42846,0.03839,0.50295,0.38849,-0.95087,0.55017,-0.14813,0.79036,0.40978,-0.33048,0.81173,0.60585,0.014413,0.86586,0.063947,1.1195,0.25425,-0.090325,1.3035,0.90609,0.62866,0.83168,0.88655,0.4843,0.60098,0.26669,0.66605,0.78468,-0.76709,0.29615,-0.8911,0.5022,-0.93834,-0.065904,0.58003,0.41217,-0.99012,-0.032054,0.69119,1.1791,-0.0059458,0.81002,0.76421,1.302,0.77637,0.7824,1.192,-0.27005,-0.24698,1.8706,0.33513,0.38592,1.1987,0.48569,0.7104,2.4307,0.68148,0.11407,0.65619,0.94468,1.245,0.44146,0.71048,0.96389,1.7647,0.22729,0.96875,-0.2738,1.2975,2.0503,0.52507,2.282,1.0773,0.44489,0.22504
CATMA1A30870,3.9909,5.1844,5.2522,5.5482,5.665,5.4666,5.4456,5.5456,5.0014,5.5408,3.9324,3.9288,4.3624,3.0828,5.4821,5.1446,4.5638,4.6449,5.2604,4.2607,4.0942,3.9892,5.1361,3.8625,3.9454,5.3148,5.188,6.088,5.2085,5.3073,5.5652,4.8358,4.6111,4.9911,3.1497,4.3796,4.2456,3.9712,5.0998,5.4383,5.0908,4.5155,4.6486,5.1233,4.4259,4.7218,3.7928,4.0384,4.1085,6.2787,5.4937,5.9637,5.4085,5.188,5.3057,5.1963,4.3807,4.8352,3.9584,3.5859,3.8535,3.9755,4.5199,5.1093,5.3526,4.1214,4.5787,3.4499,4.1962,4.6929,4.3379,4.6376,4.4774,5.2341,5.3061,5.6769,3.6244,5.1073,4.543,4.9929,4.9341,3.9829,4.4304,4.0021,3.7498,4.2972,5.3338,4.8094,4.5766,5.5171,3.1207,5.0926,3.0253,4.351,4.351,4.5253
CATMA1A65800,0.65615,0.54186,0.93488,0.2205,0.38134,0.95061,0.60157,0.66508,0.83971,1.3625,0.9037,1.1606,1.0143,0.91896,1.3587,1.2468,1.0147,0.44113,1.5196,0.60232,0.52456,0.82557,0.43697,1.3253,0.78614,0.73697,1.0593,0.010271,0.59042,0.58544,0.38307,1.0372,1.071,0.21915,1.1779,0.97341,0.95672,0.92057,1.3866,1.3884,0.99241,1.0546,1.0215,1.0144,1.1606,1.2421,0.89549,0.56747,0.99347,1.0706,1.3403,0.48719,0.30759,1.0215,0.76474,0.87313,0.47597,1.5028,1.2201,1.7923,0.64299,1.3612,1.0079,0.64145,1.0969,0.90254,0.9109,0.85213,0.55241,0.63797,1.5373,0.45586,0.59624,0.5717,0.13919,-0.012128,2.7367,0.83577,0.13422,0.13908,0.32377,0.013345,-0.017209,0.47044,1.034,1.4932,1.0067,0.57515,1.1405,0.95364,3.0214,0.14601,2.1645,1.1704,0.45205,0.83406
CATMA1C71184,4.2879,2.7256,3.306,2.2375,2.6575,4.6438,4.3899,3.8518,5.3494,3.8049,5.4095,4.5437,3.4362,4.0983,2.5059,2.7275,3.9432,3.5177,4.266,4.6446,4.9338,3.5188,3.7903,4.4867,3.9692,3.3382,3.2898,3.4103,3.3025,4.1279,4.3532,5.0625,5.756,4.7799,5.0303,4.8974,3.8698,2.887,2.7541,2.7837,3.0665,4.0168,3.7507,4.6273,5.2384,3.7049,4.5843,3.97,2.7142,3.6205,3.5394,3.3561,3.2672,4.4467,5.2044,5.2177,3.8496,5.7881,4.7594,5.0395,2.8281,2.8751,2.8322,2.6873,1.8326,3.042,3.834,4.7844,3.1947,3.2571,4.0826,4.8398,3.8147,2.7439,2.846,2.64,2.8055,3.421,3.8495,4.9367,4.6413,3.5281,4.0636,3.7144,3.4468,2.3466,1.7452,2.3151,4.022,2.9211,3.89,3.7213,4.1856,3.3613,4.0891,4.2135
CATMA1C71776,-2.0266,-0.77692,-1.3279,-0.40422,-0.38614,-0.34387,-0.44277,0.99775,1.0748,0.17831,-0.14209,-0.98905,-0.88619,0.40548,-0.37731,0.18112,-0.80473,-0.26957,0.49049,0.25413,0.30341,0.20203,-1.0343,-0.17877,-0.46107,-1.202,-0.58841,-1.0995,-1.1079,-0.10977,0.29428,0.33363,0.35537,0.55571,-0.11074,-0.69584,-0.052035,-0.18207,-0.45321,-0.2778,-0.81074,-0.27129,0.087758,0.52214,0.33791,0.51601,-0.30863,0.14386,-0.2922,-0.21013,-0.73268,-1.1732,-0.36599,0.4731,1.0357,0.62377,0.8219,0.6029,-0.27195,1.0677,-0.48423,-0.57601,-0.43393,-2.0519,-0.67433,-0.44234,0.0078619,0.40677,-0.47102,-0.59971,0.30058,-0.4604,-0.56523,-3.3913,-0.52856,-0.54137,1.0418,-0.26115,0.21246,0.37858,0.38716,-0.86708,-0.41297,-0.21536,-0.06004,-0.48526,-1.2651,-0.52592,0.23757,-0.73376,1.0272,0.59383,0.65704,-0.017658,-0.44128,-0.30226
CATMA2A41800,1.5057,1.8357,2.7851,2.9125,2.6421,2.3881,2.4772,2.3367,2.2988,3.0073,2.7659,2.8454,2.5939,2.6327,2.6184,2.3415,3.3473,2.7683,1.1123,1.9614,1.8795,2.2335,2.9227,3.1536,2.6255,2.5264,2.3874,3.3196,1.8572,2.3446,2.3358,1.683,2.1742,2.8082,2.8634,2.8607,2.6755,3.2567,2.0726,3.0746,2.8984,2.5235,2.9399,2.5731,1.9196,2.9845,2.965,2.8055,1.1878,-0.6181,2.9552,2.7814,3.0701,-0.42372,2.5897,2.6331,1.7218,-0.70788,2.9578,1.1506,3.3772,1.6571,3.3166,3.5001,2.6541,2.5367,2.8643,2.1034,2.6389,1.8915,2.4861,3.2271,1.7718,2.7359,2.391,2.7223,1.1594,2.4025,1.1524,2.1405,2.253,2.4368,2.8053,2.2955,2.2877,2.7792,3.4115,3.2464,-0.37629,3.0582,1.682,2.0598,1.8747,2.0158,2.4714,2.1816
CATMA2C47274,2.2048,1.6574,0.96502,0.15092,0.5251,0.40351,0.90106,-0.12415,0.48846,0.03794,0.86292,0.27027,0.71848,1.8535,0.47188,-0.067504,0.68578,0.28113,0.17559,0.29659,0.067618,0.79368,-0.36732,0.80945,2.4297,1.3272,1.3741,0.005024,0.57369,0.6195,0.17845,1.3991,0.71594,-0.76358,0.74421,0.078431,0.97596,0.14151,-0.77085,0.64926,-0.24602,1.3478,0.49879,0.90549,0.78024,0.94685,0.023589,0.07446,1.3597,0.19311,1.1883,-0.20756,0.59042,0.031659,0.3591,1.1757,0.97314,-1.0133,0.92409,1.2264,-0.0095851,-0.47315,1.3107,1.3967,0.80332,0.5494,1.0394,1.4519,0.50253,-0.65282,1.5689,0.17996,1.5938,0.28124,0.93511,0.10344,3.6906,0.56448,-0.40754,0.75218,0.10346,-0.37737,-0.53789,0.57109,0.29602,-0.64821,-0.52805,0.34899,0.50146,0.61456,2.1785,-0.41,2.135,0.7426,0.3307,0.64542
CATMA2C47710,3.9021,3.7272,3.709,3.494,3.7557,3.7883,3.8697,3.4952,3.6365,3.6948,4.0954,3.7629,4.1282,3.6108,4.2769,3.3689,3.5232,3.7488,3.6237,4.0805,3.855,3.8724,4.2706,3.5584,3.9576,4.1324,3.857,3.6508,3.7609,3.7885,3.6256,3.8022,3.7189,3.7417,3.6357,3.6448,4.2841,3.8731,3.6047,3.7792,3.5703,3.8284,3.8098,3.8824,4.2441,3.6127,3.8253,3.529,3.6078,4.0917,3.6794,3.7977,3.8231,3.9369,3.6087,3.7634,3.6419,4.0052,3.7083,4.0191,3.3211,3.9133,3.74,4.0801,4.0999,3.6312,3.7747,3.7768,3.7977,3.9409,3.9423,3.6708,4.1773,3.666,3.8267,3.8832,4.0462,3.8007,3.3932,4.0945,3.9901,4.1036,4.1064,3.8178,3.7936,3.8638,4.3395,3.5859,3.5698,3.7885,4.4263,4.0292,3.6857,4.1197,4.0262,3.7753
CATMA3A13690,5.2022,5.6481,5.7765,4.8253,6.0581,6.2026,5.2711,6.4481,6.0929,6.3395,5.3806,4.9156,5.3634,4.5556,5.3547,5.5214,5.6947,5.9289,5.6269,5.5406,6.0508,5.8498,5.6275,5.4422,5.3293,5.7543,5.1577,6.3626,5.429,5.7245,5.7554,5.4575,5.2244,6.2312,6.0425,5.0317,5.4494,5.5252,5.5124,5.6588,5.0015,5.7454,5.6711,6.132,5.4789,6.1668,5.6978,5.113,4.3572,5.6177,5.9557,6.0099,5.2522,5.5598,6.2427,5.4703,5.4275,5.9159,5.3029,4.1094,5.927,5.9223,5.1257,5.3835,5.6579,5.5849,5.8674,4.9425,5.2144,5.5382,4.7165,5.5688,5.2766,6.4298,5.9438,5.7105,4.757,5.9097,5.3665,5.8336,5.8393,5.6104,5.4702,5.4028,5.0756,5.632,5.9963,5.7889,5.7521,5.5561,4.0685,6.3026,4.9628,6.176,5.7256,4.8529
CATMA3A15560,0.23073,0.32331,0.37953,0.081038,-0.33446,0.18495,0.86901,0.71363,0.33531,1.4741,0.32824,0.18869,-0.34772,0.97628,0.62455,-0.14645,0.42603,-0.00031328,0.92441,0.14199,0.25522,0.55583,0.10067,1.2818,0.64424,-0.24454,0.33039,0.25975,1.1023,-0.5464,0.62174,-0.15397,0.78478,0.2999,-0.063974,0.55156,0.44076,0.17798,0.61707,0.9308,0.19809,1.2378,0.26328,0.19767,0.069484,0.76748,0.45386,0.4495,0.050625,0.99311,-0.10988,-0.070507,0.46274,0.19475,0.36696,-0.16537,1.0566,0.94446,0.85272,1.194,-0.41335,0.17202,0.38729,0.65495,-0.32063,0.60186,0.24444,1.3128,0.48551,0.55998,1.8149,0.36494,0.10693,-0.19085,0.25082,-0.10628,-0.38432,0.50117,0.97923,-0.31536,-0.2634,-0.82767,0.70017,-0.0093473,0.27653,0.67773,0.40978,0.3315,0.5179,0.32044,2.9356,-0.51529,2.7438,0.4153,0.32022,0.74311
CATMA3A21390,-0.54603,-0.32262,-0.29966,-0.22463,-0.49654,-1.0552,-1.0705,-0.93928,-0.71247,-2.7228,-0.67849,-0.24868,-1.5015,-0.22486,-0.26215,-0.34298,-0.73168,-0.33699,-0.3455,-0.5349,-0.68784,-0.47506,-1.2541,0.86942,-0.14503,-2.0603,-0.35647,-0.67731,0.20243,-1.1881,-1.3828,-1.0471,-0.20157,-2.5492,-0.7862,-0.21715,-0.20583,-0.067758,-0.86589,-0.75509,-0.62777,-0.57176,-2.0996,-0.72894,-0.56391,-1.1054,-0.94172,-0.98805,-0.20763,-0.42764,-2.0142,-1.4079,-0.66326,-0.10354,-1.6284,-1.9413,-0.77001,-0.58492,-0.99846,-0.013285,-0.31205,-0.10665,-1.2396,-1.7556,-0.40454,-0.26631,-1.2694,-0.32263,-1.2293,-0.93683,0.97994,-1.8696,-0.26859,-0.25661,-0.33193,-0.83889,-0.25944,-0.63826,0.3387,-1.4443,-0.93123,-0.84915,-0.24606,-0.63109,-0.78621,-0.40802,-0.6463,-0.84319,-1.0379,-1.1471,1.9932,-1.3029,1.5286,-0.19754,0.018446,-0.55479
CATMA3A53880,3.917,3.6689,3.7213,3.8812,3.8253,4.4861,4.258,4.7926,4.9737,4.0869,3.2183,3.5812,3.408,3.3128,3.3915,4.1923,3.9122,4.0586,4.2707,4.3077,4.8926,4.1982,3.4817,3.5267,3.6952,3.6632,3.9304,4.0793,3.9499,4.2175,4.8303,4.9599,4.6336,3.8998,3.7932,3.8572,3.2167,3.7749,4.3971,4.0662,3.9241,4.6407,4.2837,4.9644,4.972,4.2565,3.8796,3.383,3.2382,4.1017,4.058,4.0423,3.6033,4.0774,5.141,4.9736,4.4372,3.8969,3.7386,3.3618,3.539,4.2588,3.4726,3.7424,3.5818,4.9159,4.3567,4.1291,4.1108,4.4035,3.1374,3.4675,3.762,3.9264,3.7319,4.1205,2.0915,4.4192,4.5049,4.5427,4.6205,3.4653,3.6017,3.3376,3.266,3.5561,3.4538,3.761,4.2013,4.1787,4.017,4.7773,3.748,4.4977,3.8685,3.7464
CATMA5A09500,6.2838,5.1076,6.6209,5.7153,5.9395,5.3601,4.2366,5.189,3.3074,4.8701,5.0357,5.0951,6.2843,5.691,5.5054,5.9949,5.0834,5.1484,4.5884,4.805,4.458,5.0816,4.7264,5.3661,5.0645,5.8293,5.2877,5.6602,5.3336,4.7329,4.843,5.1901,3.8431,4.683,5.7106,4.0774,6.5689,5.8061,5.3445,5.2905,3.837,4.6271,4.2277,4.6165,4.0081,4.5176,4.259,4.6363,4.8557,3.9828,5.9728,5.4698,5.4102,4.5802,5.0247,4.8967,4.0116,2.6636,5.4684,4.3454,6.6893,6.5624,6.1464,5.4444,5.3309,5.6682,5.5012,4.3162,2.9028,3.3906,4.6684,4.914,5.3601,5.5138,6.2191,5.8043,5.8165,5.1155,3.8681,4.9268,4.0232,6.1699,4.6327,5.7364,6.1934,6.7188,5.0755,5.7058,5.3703,4.3921,3.2108,4.9503,4.1003,4.8225,4.6701,4.7166
CATMA5A12680,1.7891,1.362,1.4303,0.61973,0.54124,1.2733,0.7775,0.66788,1.7338,0.63125,1.5852,0.91616,1.0712,0.81919,0.90152,0.77799,1.0835,0.32735,2.0868,0.5895,1.1445,0.64545,0.71776,0.33929,1.42,1.0729,1.4879,0.86379,0.95453,1.2928,0.97753,1.1738,0.79397,0.31563,0.86345,0.67595,1.3501,1.079,1.2034,1.2432,1.3696,1.1473,0.72528,0.57199,0.85965,0.65339,0.47614,0.43219,1.363,2.4026,0.98947,0.85204,1.2591,2.3151,1.6775,1.6555,1.0371,2.5586,-0.097071,0.91744,1.068,1.6819,1.0122,0.99911,0.75267,1.2195,0.42175,0.2554,0.4819,0.80025,0.44517,0.32442,1.9863,1.5019,1.2893,1.0669,1.6881,1.7581,1.6505,1.943,2.141,1.018,0.68207,0.84392,1.1452,1.009,1.1376,1.0572,1.9258,1.7039,0.10261,1.4549,0.94693,0.77945,0.049658,0.84178
CATMA5A14990,0.41247,0.51378,0.375,-0.24526,0.027658,-0.015345,-0.028278,-0.2643,0.3905,0.12299,0.94334,0.11482,0.50109,-0.55162,0.10768,-0.26433,-0.31064,-0.76526,1.0147,-0.73178,0.3323,-0.13657,-0.14013,-0.17878,0.31259,0.36723,0.55499,-0.2664,0.31862,0.60225,0.078919,0.18282,0.23014,-0.27835,0.16392,0.58131,1.052,0.062394,0.064929,-0.11918,-0.2167,-0.26018,-0.21649,-0.032523,-0.05763,-0.62775,-0.29148,0.13633,0.72715,1.535,0.08501,0.76137,0.54934,1.5163,-0.26612,0.58127,0.30339,1.8464,-0.17161,0.30309,-0.070279,0.28016,-0.036628,0.67464,0.34753,0.26499,-0.17856,-0.61162,-0.17941,-0.01017,0.21112,0.026389,0.64566,-0.39685,0.31403,-0.21637,1.1253,0.41434,0.77759,0.20421,0.70657,0.53273,-0.67276,-0.65656,0.6997,-0.06428,-0.13546,-0.15055,0.99804,1.4673,-0.47155,-0.056436,0.84609,-0.23068,-0.55114,0.68975
CATMA5A25890,-0.23072,0.82252,0.32512,0.13284,0.14406,0.005071,0.40953,-0.11252,-0.6367,-0.048073,0.21325,-0.046316,-0.35078,1.1023,-0.019882,-0.55825,-0.34621,0.1114,0.030302,-0.08142,0.19157,0.5152,-0.034952,0.20984,1.0547,0.4816,0.31078,0.14731,0.31811,-0.27275,-0.47217,-0.043207,0.29109,0.41192,-1.069,0.23357,-0.17453,0.015661,-0.26869,0.14587,0.19336,0.5926,-0.1583,0.61242,0.18635,0.01207,-0.21772,0.13986,1.9305,0.3349,0.62954,-0.04455,1.121,-0.14155,-0.33772,-0.42633,0.41828,-0.29794,-0.7107,1.4786,-0.37442,-0.45371,0.16175,-0.057764,-0.11803,-0.037838,0.25868,0.88605,0.33225,-0.24331,0.93084,-0.33266,0.9762,0.24755,0.30857,0.14661,1.8351,0.40313,0.45084,-0.52105,-0.31271,-0.37122,-0.28615,-0.0023692,-0.43072,-0.24417,-0.5184,0.13874,-0.32606,-0.1705,2.1396,-0.77657,2.3056,0.32096,0.29337,-0.034746
CATMA5A31940,4.4307,4.8735,4.7911,5.8201,5.9587,5.576,5.9084,5.849,5.2832,5.5423,5.0275,4.5254,4.5054,3.0696,5.6512,4.3986,4.9856,4.9222,4.951,4.5506,4.2185,4.3184,5.4783,4.4515,3.9397,5.6269,5.0988,6.1254,5.7446,5.6146,5.452,5.2047,5.3527,5.93,4.8931,5.5529,3.9876,4.1072,4.0583,5.4324,5.4681,4.392,4.5189,5.0629,4.9347,5.2165,4.6681,4.7428,4.1539,6.3376,5.353,6.2896,5.5844,5.1654,5.4391,5.3933,5.261,5.6974,4.5142,3.9851,3.569,4.0946,4.6662,5.1085,5.0319,4.4598,4.8672,3.7326,5.3032,5.0448,4.7771,4.2209,4.1886,4.284,5.4681,5.8331,4.7683,5.6614,5.3313,5.2017,5.1002,5.0642,4.4867,4.8576,4.1454,4.0971,5.0368,4.845,4.753,5.5496,2.9838,5.1394,3.342,4.1246,5.0121,4.618
Code proper (BHC is from Bioconductor):
library(argparse)
library(RColorBrewer)
library(BHC)
library(parallel)
library(gplots)
#data prep and clustering, to get dendrograms etc as shown in plot
data = read.csv('input.csv',header=TRUE,row.names=1,check.names=FALSE)
genes = rownames(data)
samples = colnames(data)
data = data.matrix(data)
standardisedData = (data-mean(data))/sd(data)
samples = as.numeric(samples)
hc = bhc(standardisedData, genes, timePoints=samples, dataType='time-course', verbose=TRUE)
#the plotting proper
png('heatmap.png',width=6,height=6,units='in',res=300)
heatmap.2(standardisedData, Colv=NA, Rowv=hc, tracecol=NA, scale="none", col=brewer.pal(11,'RdBu'))
#heatmap.2(standardisedData, Colv=NA, Rowv=hc, tracecol=NA, scale="none", col=brewer.pal(11,'RdBu'), margins=c(3,10)) <- this fixes it on a single-case basis
dev.off()
I would suggest just giving it a fairly wide default margin, such that it should be clipped even with longer labels, e.g.:
heatmap.2(standardisedData, Colv=NA, Rowv=hc, tracecol=NA, scale="none", col=brewer.pal(11,'RdBu'), margins=c(14, 14))
The default margin size is (5,5). The above increases the both the column and row margins, but you can increase just one or the other as well.
If you want to be more precise, you could try using max(strwidth(rownames(standardisedData))) to determine the amount of space needed by the largest label, and then convert that into the units expected by par(mar=*) (what heatmap.2() uses to specify plot margins.)
I think this should do the trick:
# determine margins to use
png('/tmp/trash', width=6,height=6,units='in',res=300)
plot.new()
margin_width = max(strwidth(rownames(standardisedData), units='inches')) * par('fin')[1]
dev.off()
#the plotting proper
png('heatmap.png',width=6,height=6,units='in',res=300)
heatmap.2(standardisedData, Colv=NA, Rowv=hc, tracecol=NA, scale="none", col=brewer.pal(11,'RdBu'), margins=c(5, margin_width))
dev.off()
Related
R rasterVis levelplot: a white line erroneously appears
I am plotting maps of atmospheric pollutant fields, or meteorological field, difference between such fields, often overlayed with orography. My fields are gridded. A white line misteriously appears, sometimes two. This seems to happen a bit randomly. I mean: same code and fields, same line; but when I change fields, or color scales, it changes position, or it disappears, or another one appears. Sometimes horizontal, sometimes vertical. Here is my code #!/usr/bin/env Rscript library(rasterVis) library(RColorBrewer) NX <- 468 NY <- 421 hgt <- matrix(0.,NX,NY) # read from file: ucon <- file("hgt.dat", open="rb") for (n in seq(1,NX)) { hgt[n,] <- readBin(ucon, "numeric", n=NY, size=4) } close(ucon) hgtbks <- c(-100,10,500,1000,1500,2000,2500,3000,3500) hgtcols <- colorRampPalette(c("gray30","white"))(length(hgtbks)-1) tit <- "Orography" bkstart=50.0; bkmax=1500.; bkby=100. bks <- seq(bkstart, bkmax, bkby) nbks <- length(bks) cols <- rev(colorRampPalette(brewer.pal(11,"Spectral"))(nbks-2)) cols <- c("white",cols) legendbreaks <- seq(1,nbks) legendlabels <- formatC(bks,digits=3) legendlabpos <- legendbreaks rpl <- levelplot(hgt, margin=FALSE , col.regions= hgtcols, at= hgtbks , main= list(label=tit, cex=1.8) , colorkey=list(draw= TRUE, col=cols, at=legendbreaks , labels=list(labels=legendlabels, at=legendlabpos, cex=1.2)) , xlab=NULL, ylab=NULL, scales= list(draw= FALSE)) png("whiteline.png", width=800, height=840) plot(rpl) graphics.off() I would really like to upload a file with my data, but for the moment I could not find a way to do it (I don't think I can do it, not even an ASCII file). The data matrix (468x421) is too big to be explicitly included in the code, but it really is the orography file shown in the picture (elevation in meters above mean sea level). And here is the resulting "white line" map: Really, I think this might be a levelplot bug. It seems to happen both when hgt is a matrix and when it is a proper raster object: this doesn't seem to make a difference. Any idea?
I think I found a workaround. By setting zero padding on the 4 sides, I managed to make the whiteline disappear from a series of maps. First I defined: zpadding <- list(layout.heights= list(top.padding=0, bottom.padding=0), layout.widths= list(left.padding=0, right.padding=0)) then I added, among the parameters of the levelplot call: par.settings=zpadding As I said, I don't think this is a proper solution, but a workaround. The problem seems related to any rescaling of the plot area. In fact, when a rescaling is forced by, for example, having 4 or 5 digits (instead of 2 or 3) in the colorbar labels, a white line may reappear. I hope this may point in the right direction other people, either users or developers of levelplot and related software.
igraph ggplot rStudio How can I make lines between nodes longer and add arrows? Also how can I make the legend smaller?
I have a really wordy network plot. I am basically trying to have it function as a sort of flow chart. I am trying to make its aesthetics both functional and pleasing, but I am having a difficult time. The legend's text is way too large and there is not enough space in the network for everything to be spaced out properly. Also, I want to make the background a different color. The only solutions I have been able to find, however, require the ggnet2 package, but when I try to install the ggnet2 package, it says I cannot install that on this version of rStudio. When I tried to update my rStudio, it says that I have the most recent version of rStudio. I do not know what else to try. Any help would be much appreciated! This is my code: library(igraph) library(RColorBrewer) links <- data.frame( source=c("Pubertal Hormones, Timing, and Development","Pubertal Hormones, Timing, and Development","Pubertal Hormones, Timing, and Development","Pubertal Hormones, Timing, and Development","Genetic Vulnerability","Genetic Vulnerability","Temperament","Temperament","Depressogenic Vulnerability","Negative Cognitive Style","Negative Cognitive Style","Objectified Body Consciousness","Objectifed Body Consciousness","Rumination","Peer Sexual Harassment","Peer Sexual Harassment"), target=c("Genetic Vulnerability","Objectified Body Consciousness","Peer Sexual Harassment","Depressogenic Vulnerability","Temperament","Depressogenic Vulnerability","Negative Cognitive Style","Depressogenic Vulnerability","Gender Difference in Depression","Rumination","Depressogenic Vulnerability","Rumination","Depressogenic Vulnerability","Depressogenic Vulnerability","Objectified Body Consciousness","Gender Difference in Depression"), importance=(sample(1:4, 16, replace=T)) ) V = c(links$source, links$target) %>% unique() nodes <- data.frame( name=V, carac=c( rep("Biological Vulnerability",2),rep("Affective Vulnerability",3),rep("Cognitive Vulnerability",3),rep("Negative Life Events",2)) ) network <- graph_from_data_frame(d=links, vertices=nodes, directed=F) coul <- brewer.pal(4, "Set3") my_color <- coul[as.numeric(as.factor(V(network)$carac))] plot(network, vertex.color=my_color,vertex.shape=c("vrectangle"),vertex.size=c(150),vertex.label.cex=c(0.5)) legend("bottom", legend=levels(as.factor(V(network)$carac)) , col = coul , bty = "n", pch=20 , pt.cex = 3, cex = 1, text.col=coul , horiz = TRUE, inset = c(0.1, 0.1))
With a small graph like this, you can customize the layout so that things look nicer. We'll just step through the problems one at a time. Let's start from your plot statement, but let's make it reproducible by setting the random seed. set.seed(123) plot(network, vertex.color=my_color,vertex.shape=c("vrectangle"), vertex.size=c(150),vertex.label.cex=c(0.5)) The biggest problem is that the plot does not use all of the space in the graphics window. You can adjust that some with the margin parameter. When I do that, the boxes seem too big, so I will make them a bit smaller at the same time and also change the text size to match the new boxes. set.seed(123) LO = layout_nicely(network) plot(network, layout=LO, margin=-0.6, vertex.color=my_color, vertex.shape=c("vrectangle"), vertex.size=c(100), vertex.label.cex=c(0.7)) OK, this is better, but there still are some problems. First, the box for "Pubertal Hormones, Timing, and Development" is too small. We can adjust that by using a vector of vertex sizes. When we change that, there are some other changes in the plot, so let's just make that one change first. VS = rep(100, vcount(network)) VS[1] = 150 plot(network, layout=LO, margin=-0.7, vertex.color=my_color, vertex.shape=c("vrectangle"), vertex.size=VS, vertex.label.cex=c(0.7)) Next, some of the boxes overlap. We can fix those by editing the layout matrix. This matrix is just the x,y coordinates at which to plot the nodes. I just looked at the matrix and adjusted the positions a little. LO[1,] = c(6.3,7.3) LO[4,] = c(5.4,6.7) LO[5,] = c(5,5.5) LO[7,] = c(7.4,6.8) LO[8,] = c(5.1,6.2) LO[9,] = c(5.2,8.4) LO[10,] = c(7,8.3) plot(network, layout=LO, margin=-0.7, vertex.color=my_color, vertex.shape=c("vrectangle"), vertex.size=VS, vertex.label.cex=c(0.7)) This is pretty good. More could be done, but I think the method is clear, so I will leave any additional aesthetic adjustments of the nodes to you. Now to finish up, you wanted to adjust the background color. You can do that (before plotting) by setting bg using par. The final version is: par(bg="lightblue1") plot(network, layout=LO, margin=-0.7, vertex.color=my_color, vertex.shape=c("vrectangle"), vertex.size=VS, vertex.label.cex=c(0.7))
Controlling margins in a genoPlotR plot_gene_map
I'm producing a plot_gene_map figure by the genoPlotR R package, which gives a horizontal phylogenetic tree where aligned with each leaf is a genomic segment. Here's a simple example that illustrates my usage and problem: The plot_gene_map function requires an ade4s' package phylog object which represents the phylogenetic tree: tree <- ade4::newick2phylog("(((A:0.08,B:0.075):0.028,(C:0.06,D:0.06):0.05):0.0055,E:0.1);") A list of genoPlotR's dna_seg objects (which are essentially data.frames with specific columns), where the names of the list elements have to match the names of the leaves of tree: dna.segs.list <- list(A=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.A.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="red")), B=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.B.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="blue")), C=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.C.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="green")), D=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.D.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="yellow")), E=genoPlotR::as.dna_seg(data.frame(name=paste0("VERY.LONG.NAME.E.",1:10),start=seq(1,91,10),end=seq(5,95,10),strand=1,col="black",ly=1,lwd=1,pch=1,cex=1,gene_type="blocks",fill="orange"))) And a list of genoPlotR's annotation objects, which give coordinate information, also named according to the tree leaves: annotation.list <- lapply(1:5,function(s){ mids <- genoPlotR::middle(dna.segs.list[[s]]) return(genoPlotR::annotation(x1=mids,x2=NA,text=dna.segs.list[[s]]$name,rot=30,col="black")) }) names(annotation.list) <- names(dna.segs.list) And the call to the function is: genoPlotR::plot_gene_map(dna_segs=dna.segs.list,tree=tree,tree_width=2,annotations=annotation.list,annotation_height=1.3,annotation_cex=0.9,scale=F,dna_seg_scale=F) Which gives: As you can see the top and right box (gene) names get cut off. I tried playing with pdf's width and height, when saving the figure to a file, and with the margins through par's mar, but they have no effect. Any idea how to display this plot without getting the names cut off? Currently genoPlotR's plot_gene_map does not have a legend option implemented. Any idea how can I add a legend, let's say which shows these colors in squares aside these labels: data.frame(label = c("A","B","C","D","E"), color = c("red","blue","green","yellow","orange"))
Glad that you like genoPlotR. There are no real elegant solution to your problem, but here are a few things you can attempt: - increase annotation_height and reduce annotation_cex - increase rotation (“rot”) in the annotation function - use xlims to artificially increase the length of the dna_seg (but that’s a bad hack) For the rest (including the legend), you’ll have to use grid and its viewports. A blend of the first 3 solutions: annotation.list <- lapply(1:5,function(s){ mids <- genoPlotR::middle(dna.segs.list[[s]]) return(genoPlotR::annotation(x1=mids, x2=NA, text=dna.segs.list[[s]]$name,rot=75,col="black")) }) names(annotation.list) <- names(dna.segs.list) genoPlotR::plot_gene_map(dna_segs=dna.segs.list,tree=tree,tree_width=2,annotations=annotation.list,annotation_height=5,annotation_cex=0.4,scale=F,dna_seg_scale=F, xlims=rep(list(c(0,110)),5)) For the better solution with grid: (note the "plot_new=FALSE" in the call to plot_gene_map) # changing rot to 30 annotation.list <- lapply(1:5,function(s){ mids <- genoPlotR::middle(dna.segs.list[[s]]) return(genoPlotR::annotation(x1=mids,x2=NA,text=dna.segs.list[[s]]$name,rot=30,col="black")) }) names(annotation.list) <- names(dna.segs.list) # main viewport: two columns, relative widths 1 and 0.3 pushViewport(viewport(layout=grid.layout(1,2, widths=unit(c(1, 0.3), rep("null", 2))), name="overall_vp")) # viewport with gene_map pushViewport(viewport(layout.pos.col=1, name="geneMap")) genoPlotR::plot_gene_map(dna_segs=dna.segs.list,tree=tree,tree_width=2,annotations=annotation.list,annotation_height=3,annotation_cex=0.5,scale=F,dna_seg_scale=F, plot_new=FALSE) upViewport() # another viewport for the margin/legend pushViewport(viewport(layout.pos.col=2, name="legend")) plotLegend(…) upViewport() Hope that helps! Lionel
Which function or package could I use to add the legend? The R base functions did not seem to work for me. The following message is displayed: Error in strheight(legend, units = "user", cex = cex) : plot.new has not been called yet"
Combining multiple complex plots as panels in a single figure
Introduction by #backlin Multiple simple plots can combined as panels in a single figure by using layout or par(mfrow=...). However, more complex plots tend to setup their own panel layout internally disabling them from being used as panels. Is there a way to create a nested layout and encapsulating a complex plot into a single panel? I have a feeling the grid package can accomplish this, e.g. by ploting the panels in separate viewports, but haven't been able to figure out how. Here is a toy example to demonstrate the problem: my.plot <- function(){ a <- matrix(rnorm(100), 10, 10) plot.new() par(mfrow=c(2,2)) plot(1:10, runif(10)) plot(hclust(dist(a))) barplot(apply(a, 2, mean)) image(a) } layout(matrix(1:4, 2, 2)) for(i in 1:4) my.plot() # How to avoid reseting the outer layout when calling `my.plot`? Original question by #alittleboy I use the heatmap.2 function in the gplots package to generate heatmaps. Here is a sample code for a single heatmap: library(gplots) row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10) heatmap.2(row.scaled.expr, dendrogram ='row', Colv=FALSE, col=greenred(800), key=FALSE, keysize=1.0, symkey=FALSE, density.info='none', trace='none', colsep=1:10, sepcolor='white', sepwidth=0.05, scale="none",cexRow=0.2,cexCol=2, labCol = colnames(row.scaled.expr), hclustfun=function(c){hclust(c, method='mcquitty')}, lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ), ) However, since I want to compare multiple heatmaps in a single plot, I use par(mfrow=c(2,2)) and then call heatmap.2 four times, i.e. row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10) arr <- array(data=row.scaled.expr, dim=c(dim(row.scaled.expr),4)) par(mfrow=c(2,2)) for (i in 1:4) heatmap.2(arr[ , ,i], dendrogram ='row', Colv=FALSE, col=greenred(800), key=FALSE, keysize=1.0, symkey=FALSE, density.info='none', trace='none', colsep=1:10, sepcolor='white', sepwidth=0.05, scale="none",cexRow=0.2,cexCol=2, labCol = colnames(arr[ , ,i]), hclustfun=function(c){hclust(c, method='mcquitty')}, lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ), ) However, the result is NOT four heatmaps in a single plot, but four separate heatmaps. In other words, if I use pdf() to output the result, the file is four pages instead of one. Do I need to change any parameters somewhere? Thank you so much!
Okay. I suppose this question has been sitting unanswered for enough time that the long answer should be written up. The answer to most difficult graphics issues is (as #backlin suggests) the raw use of the 'grid' package. Many prebuilt graphics packages override all current viewports and plot device settings, so if you want something done a very specific way, you have to build it yourself. I recommend picking up Paul Murrell's book "R Graphics" and going over the chapter on the 'grid' package. It's a crazy useful book, and a copy sits on my desk all the time. For your heatmap, I've written up a quick primer that will get you started quickly. Functions to know grid.newpage() This initializes the plotting device. Use it without parameters. grid.rect() This draws a rectangle. Your heatmap is basically just a giant set of colored rectangles, so this will be bulk of your graphic. It works like so: grid.rect(x=x_Position, y=y_Position, width=width_Value, height=height_Value, gp=gpar(col=section_Color, fill=section_Color), just=c("left", "bottom"), default.units="native") The 'just' argument specifies which point of the rectangle will sit on your specified (x, y) coordinates. grid.text() This draws text. It works like so: grid.text("Label Text", x_Value, y_Value, gp=gpar(col=color_Value, cex=font_Size), just=c("right","center"), rot=rot_Degrees, default.units="native") grid.lines() This draws a line. It works like so: grid.lines(c(x_Start,x_End), c(y_Start, y_End), gp=gpar(col=color_Value), default.units="native") dataViewport() This defines the attributes of a plotting window, which 'grid' refers to as a "viewport." Use it like so: pushViewport(dataViewport(xData=x_Data, yData=y_Data, xscale=c(x_Min, x_Max), yscale=c(y_Min, y_Max), x=x_Value, y=y_Value, width=width_Value, height=height_Value, just=c("left","center"))) There is some stuff to keep in mind here... see the more detailed explanation of viewports. pushViewport() This is used to initialize a veiwport. You wrap this around a viewport definition to actually execute the viewport, like so: pushViewport(dataViewport([stuff in here])) popViewport() This finalizes a viewport and moves you up one level in the hierarchy of viewports. See the more detailed explanation of viewports. Viewports in a nutshell Viewports are temporary drawing spaces that define where and how 'grid' objects will be drawn. Everything inside the viewport is drawn relative to the viewport. If the viewport is rotated, everything inside will be rotated. Viewports can be nested, can overlap, and are almost infinitely flexible, with one exception: they are always a rectangle. Something that messes a lot of people up initially is the coordinate system. Every viewport, including the initial 'grid.newpage()' viewport, goes from 0 to 1 on both the x and y axes. The origin (0,0) is the far lower left corner, and the max (1,1) is the far upper right corner. This is the "npc" unit system, and everything that doesn't have a set of units specified will likely end up being drawn according to this system. This means two things for you: Use the "npc" system when specifying viewport sizes and locations. Just assume that your viewports have to use the "npc" coordinates, and you'll save yourself a LOT of hassle. This means if I want to draw two plots next to each other, the definitions for the two viewports would look something like: viewport(x=0, y=0, width=0.5, height=1, just=c("left","lower")) and viewport(x=0.5, y=0, width=0.5, height=1, just=c("left","lower")) If your viewport has a different coordinate system (for example a viewport for plotting a graph), then you will need to specify the 'default.units' argument for every 'grid' object you draw. For instance, if you tried to plot a point at (2,4) you would never see the point, because it would be far off-screen. Specifying default.units="native" would tell that point to use the viewport's own coordinate system and would draw the point correctly. Viewports can be navigated and written to directly, but unless you're doing something very automated, it is easier to specify a viewport, draw inside it, and then "pop" (finalize) the viewport. This returns you to the parent viewport, and you can start on the next viewport. Popping each viewport is a clutter-free approach and will suit most purposes (and make it easier to debug!). The 'dataViewport' function is all important when plotting a graph. This is a special type of viewport that handles all of the coordinates and scales for you, as long as you tell it what data you are using. This is the one I use for any plotting area. When I first started using the 'grid' package, I adjusted all of my values to fit the "npc" coordinate system, but that was a mistake! The 'dataViewport' function makes is all easy as long as you remember to use the "native" units for each drawing item. Disclaimer Data visualization is my forte, and I don't mind spending half a day scripting up a good visual. The 'grid' package allows me to create quite sophisticated visuals faster than anything else I found. I script up my visuals as functions, so I can load various data quickly. I couldn't be happier. However, if you don't like to script things, 'grid' will be your enemy. Also, if you consider half a day to be too much time for a visual, then 'grid' won't help you too much. The (in)famous 'ggplot2' package is what most people settle on, and I heartily recommend it, even though I don't personally find it useful. If someone wants help learning 'grid' graphics, I'm more than willing to help teach. It has completely revolutionized my ability to create fast, intelligent, and good-looking data visuals.
The gridGraphics package might help, library(gridGraphics) library(grid) grab_grob <- function(){ grid.echo() grid.grab() } arr <- replicate(4, matrix(sample(1:100),nrow=10,ncol=10), simplify = FALSE) library(gplots) gl <- lapply(1:4, function(i){ heatmap.2(arr[[i]], dendrogram ='row', Colv=FALSE, col=greenred(800), key=FALSE, keysize=1.0, symkey=FALSE, density.info='none', trace='none', colsep=1:10, sepcolor='white', sepwidth=0.05, scale="none",cexRow=0.2,cexCol=2, labCol = colnames(arr[[i]]), hclustfun=function(c){hclust(c, method='mcquitty')}, lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ), ) grab_grob() }) grid.newpage() library(gridExtra) grid.arrange(grobs=gl, ncol=2, clip=TRUE)
I struggled with a similar problem and came up with a solution that is very easy but requires imagemagick installed. The idea is to plot the heatmaps to separate files and then combine them with the montage command: library(gplots) row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10) arr <- array(data=row.scaled.expr, dim=c(dim(row.scaled.expr),4)) par(mfrow=c(2,2)) for (i in 1:4) { ifile <- paste0(i,'_heatmap.pdf') pdf(ifile) heatmap.2(arr[ , ,i], dendrogram ='row', Colv=FALSE, col=greenred(800), key=FALSE, keysize=1.0, symkey=FALSE, density.info='none', trace='none', colsep=1:10, sepcolor='white', sepwidth=0.05, scale="none",cexRow=0.2,cexCol=2, labCol = colnames(arr[ , ,i]), hclustfun=function(c){hclust(c, method='mcquitty')}, lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ), ) dev.off() } system('montage -geometry 100% -tile 2x2 ./*_heatmap.pdf outfile.pdf')
Just as Dinre said, the "grid" pacakge can handle all complex plots. For the original question by #alittleboy, I think the package "ComplexHeatmap" (which is also base on grid) from Bionconductor can be a nice solution (http://www.bioconductor.org/packages/release/bioc/vignettes/ComplexHeatmap/inst/doc/ComplexHeatmap.html)
Trying to determine why my heatmap made using heatmap.2 and using breaks in R is not symmetrical
I am trying to cluster a protein dna interaction dataset, and draw a heatmap using heatmap.2 from the R package gplots. My matrix is symmetrical. Here is a copy of the data-set I am using after it is run through pearson:DataSet Here is the complete process that I am following to generate these graphs: Generate a distance matrix using some correlation in my case pearson, then take that matrix and pass it to R and run the following code on it: library(RColorBrewer); library(gplots); library(MASS); args <- commandArgs(TRUE); matrix_a <- read.table(args[1], sep='\t', header=T, row.names=1); mtscaled <- as.matrix(scale(matrix_a)) # location <- args[2]; # setwd(args[2]); pdf("result.pdf", pointsize = 15, width = 18, height = 18) mycol <- c("blue","white","red") my.breaks <- c(seq(-5, -.6, length.out=6),seq(-.5999999, .1, length.out=4),seq(.100009,5, length.out=7)) #colors <- colorpanel(75,"midnightblue","mediumseagreen","yellow") result <- heatmap.2(mtscaled, Rowv=T, scale='none', dendrogram="row", symm = T, col=bluered(16), breaks=my.breaks) dev.off() The issue I am having is once I use breaks to help me control the color separation the heatmap no longer looks symmetrical. Here is the heatmap before I use breaks, as you can see the heatmap looks symmetrical: Here is the heatmap when breaks are used: I have played with the cutoff's for the sequences to make sure for instance one sequence does not end exactly where the other begins, but I am not able to solve this problem. I would like to use the breaks to help bring out the clusters more. Here is an example of what it should look like, this image was made using cluster maker: I don't expect it to look identical to that, but I would like it if my heatmap is more symmetrical and I had better definition in terms of the clusters. The image was created using the same data.
After some investigating I noticed was that after running my matrix through heatmap, or heatmap.2 the values were changing, for example the interaction taken from the provided data set of Pacdh-2 and pegg-2 gave a value of 0.0250313 before the matrix was sent to heatmap. After that I looked at the matrix values using result$carpet and the values were then -0.224333135 -1.09805379 for the two interactions So then I decided to reorder the original matrix based on the dendrogram from the clustered matrix so that I was sure that the values would be the same. I used the following stack overflow question for help: Order of rows in heatmap? Here is the code used for that: rowInd <- rev(order.dendrogram(result$rowDendrogram)) colInd <- rowInd data_ordered <- matrix_a[rowInd, colInd] I then used another program "matrix2png" to draw the heatmap: I still have to play around with the colors but at least now the heatmap is symmetrical and clustered. Looking into it even more the issue seems to be that I was running scale(matrix_a) when I change my code to just be mtscaled <- as.matrix(matrix_a) the result now looks symmetrical.
I'm certainly not the person to attempt reproducing and testing this from that strange data object without code that would read it properly, but here's an idea: ..., col=bluered(20)[4:20], ... Here's another though which should return the full rand of red which tha above strategy would not: shift.BR<- colorRamp(c("blue","white", "red"), bias=0.5 )((1:16)/16) heatmap.2( ...., col=rgb(shift.BR, maxColorValue=255), .... ) Or you can use this vector: > rgb(shift.BR, maxColorValue=255) [1] "#1616FF" "#2D2DFF" "#4343FF" "#5A5AFF" "#7070FF" "#8787FF" "#9D9DFF" "#B4B4FF" "#CACAFF" "#E1E1FF" "#F7F7FF" [12] "#FFD9D9" "#FFA3A3" "#FF6C6C" "#FF3636" "#FF0000" There was a somewhat similar question (also today) that was asking for a blue to red solution for a set of values from -1 to 3 with white at the center. This it the code and output for that question: test <- seq(-1,3, len=20) shift.BR <- colorRamp(c("blue","white", "red"), bias=2)((1:20)/20) tpal <- rgb(shift.BR, maxColorValue=255) barplot(test,col = tpal) (But that would seem to be the wrong direction for the bias in your situation.)