[R] barplot: segment-wise shading

Marc Schwartz marc_schwartz at me.com
Fri Jan 17 00:59:13 CET 2014


On Jan 16, 2014, at 5:03 PM, Martin Weiser <weiser2 at natur.cuni.cz> wrote:

> Marc Schwartz píše v Čt 16. 01. 2014 v 16:46 -0600:
>> On Jan 16, 2014, at 12:45 PM, Martin Weiser <weiser2 at natur.cuni.cz> wrote:
>> 
>>> Dear listers,
>>> 
>>> I would like to make stacked barplot, and to be able to define shading
>>> (density or angle) segment-wise, i.e. NOT like here:
>>> # Bar shading example
>>>    barplot(VADeaths, angle = 15+10*1:5, density = 20, col = "black",
>>>            legend = rownames(VADeaths))
>>> 
>>> The example has 5 different angles of shading, I would like to have as
>>> many possible angle values as there are segments (i.e. 20 in the
>>> VADeaths example).
>>> I was not successful using web search.
>>> Any advice?
>>> 
>>> Thank you for your patience.
>>> With the best regards,
>>> Martin Weiser
>> 
>> 
>> You could do something like this:
>> 
>> # Get the dimensions of VADeaths
>>> dim(VADeaths)
>> [1] 5 4
>> 
>> # How many segments?
>>> prod(dim(VADeaths))
>> [1] 20
>> 
>> 
>> Then use that value in the barplot() arguments as you desire, for example:
>> 
>>  barplot(VADeaths, angle = 15 + 10 * 1:prod(dim(VADeaths)), 
>>          density = 20, col = "black", legend = rownames(VADeaths))
>> 
>> 
>> or wrap the barplot() function in your own, which pre-calculates the values and then passes them to the barplot() call in the function.
>> 
>> See ?dim and ?prod
>> 
>> Be aware that a vector (eg. 1:5) will be 'dim-less', thus if you are going to use this approach for a vector based data object, you would want to use ?length
>> 
>> Regards,
>> 
>> Marc Schwartz
>> 
> 
> Hello,
> 
> thank you for your attempt, but this does not work (for me).
> This produces 5 angles of shading, not 20.
> Maybe because of my R version (R version 2.15.1 (2012-06-22); Platform:
> i486-pc-linux-gnu (32-bit))?
> 
> Thank you.
> 
> Regards,
> Martin Weiser


Arggh.

No, this is my error for not actually looking at the plot and presuming that it would work.

Turns out that it does work for a non-stacked barplot:

  barplot(VADeaths, angle = 1:20 * 10, density = 10, beside = TRUE)

However, internally within barplot(), actually barplot.default(), the manner in which the matrix is passed to an internal function called xyrect() to draw the segments, is that entire columns are passed, rather than the individual segments (counts), when the bars are stacked.

As a result, due to the vector based approach used, only the first 5 values of 'angle' are actually used, since there are 5 columns, rather than all 20. The same impact will be observed when using the default legend that is created.

Thus, I don't believe that there will be an easy (non kludgy) way to do what you want, at least with the default barplot() function. 

You could fairly easily create/build your own function using ?rect, which is what barplot() uses to draw the segments. I am not sure if lattice based graphics can do this or perhaps using Hadley's ggplot based approach would offer a possibility.

Apologies for the confusion.

Regards,

Marc




More information about the R-help mailing list