简体   繁体   中英

R: A box for the legends and labels written at a given angle with ggplot2 package or barplot function

My question is certainly a repeat but I can't figure out how to achieve what I aim to make.

Here is my data:

v1=c(46.55172, 13.79310, 29.31034,  1.72414,  5.17241,  3.44828,  0.00000,  0.60241, 24.09639, 59.63855,  4.81928,  6.02410,  0.00000,  4.81928, 14.58333, 22.91667, 58.33333, 0.00000,  2.08333,  2.08333,  0.00000, 20.96774, 20.96774, 47.58065,  5.64516,  3.22581,  0.80645,  0.80645)

names(v1) = c('Simul','SE','Obs','CG','Double','LR','RM','Simul','SE','Obs','CG','Double','LR','RM','Simul','SE','Obs', 'CG','Double','LR','RM','Simul','SE','Obs','CG', 'Double','LR','RM')

The first 7 numbers correspond to a fist "journal", the numbers from 8 to 14 corresponds to a second "journal", etc...

The seven numbers of each journal have the names Simul, SE, Obs, CG, Double, LR, RM. I want these numbers to represent the height of seven bars respectiviely in barplot and I want the 4 journals to be on the same window. My current script does so.

par(mfrow=c(2,2))
for (journal in 0:3){
    if (journal == 0) { journal.name = 'American Naturalist'}
    if (journal == 1) { journal.name = 'Animal Behavour'}
    if (journal == 2) { journal.name = 'Ecology Letters'}
    if (journal == 3) { journal.name = 'Evolution'} 
    barplot(v1[((journal*7)+1):((journal*7)+7)],ylim=c(0,60),main=journal.name)
}
mtext('Frequency',padj=2,side=2,outer=T)
mtext('Articles Type',padj=-2,side=1,outer=T)

在此处输入图片说明

I now want to...

1) legend

... add a box (and the space for this box) on the right side in order to add some legend with the meaning of the abreviations (Simul, SE, OBS, etc...)

2) text angle

... write the abreviations (Simul, SE, OBS, etc...) with an angle of 45°.

I guess the best way to achieve these things is to use ggplot but any answer types are welcome !

Thanks a lot !

For starters, I would recommend reshaping your current data ( v1 ) to fit ggplot2

df = do.call("rbind",lapply(unique(names(v1)),function(x){v1[names(v1)==x]}))
rownames(df) = unique(names(v1))
colnames(df) = c("American Naturalist","Animal Behavour","Ecology Letters","Evolution")

head(df)
       American Naturalist Animal Behavour Ecology Letters Evolution
Simul             46.55172         0.60241        14.58333  20.96774
SE                13.79310        24.09639        22.91667  20.96774
Obs               29.31034        59.63855        58.33333  47.58065
CG                 1.72414         4.81928         0.00000   5.64516
Double             5.17241         6.02410         2.08333   3.22581
LR                 3.44828         0.00000         2.08333   0.80645

Now, using reshape2 :

head(melt(df))
    Var1                Var2    value
1  Simul American Naturalist 46.55172
2     SE American Naturalist 13.79310
3    Obs American Naturalist 29.31034
4     CG American Naturalist  1.72414
5 Double American Naturalist  5.17241
6     LR American Naturalist  3.44828

Next, a basic ggplot2 bar plot:

p = ggplot(melt(df)) + geom_bar(aes(x=Var1,y=value, fill=Var1), stat="identity") + facet_wrap(~Var2)

The angle of axis labels:

p <- p + theme(axis.text.x = element_text(angle = 45))

在此处输入图片说明

I guess you can build on this by looking at labs for adding explanations for the axis labels.

As @Aaron said, it might be better to flip the plot around:

p + coord_flip()

在此处输入图片说明

OK, for one thing, let's put your data in a matrix. Too hard to keep track in just a vector!

v2 <- matrix(v1, nrow=7)
rownames(v2) <-  c('Simul','SE','Obs','CG','Double','LR','RM')
colnames(v2) <- c('American Naturalist','Animal Behavour','Ecology Letters','Evolution')
v2
#        American Naturalist Animal Behavour Ecology Letters Evolution
# Simul             46.55172         0.60241        14.58333  20.96774
# SE                13.79310        24.09639        22.91667  20.96774
# Obs               29.31034        59.63855        58.33333  47.58065
# CG                 1.72414         4.81928         0.00000   5.64516
# Double             5.17241         6.02410         2.08333   3.22581
# LR                 3.44828         0.00000         2.08333   0.80645
# RM                 0.00000         4.81928         0.00000   0.80645

You're probably right that ggplot or lattice are going to be preferred solutions; here's a lattice one.

library(lattice)
library(reshape2)
v3 <- melt(v2)
names(v3) <- c("Variable", "Journal", "Frequency")
barchart(Variable~Frequency|Journal, data=v3, as.table=TRUE)

在此处输入图片说明

Note that I've made the bars horizontal and that this way the labels for each bar can be easily read. This is preferred to putting them at an angle and giving your audience a pain in the neck. This also makes it possible to just use the full name of whatever those things are instead of just the abbreviations, rather than putting it in a legend and giving your audience whiplash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM