5

In this barplot, the legend is blocking off a portion of it. How can I reduce the size of the legend?

My code:

`work.gender.marriage.table = table(work$marriage,work$gender)`

enter image description here

`barplot(work.gender.marriage.table,main = "Gender & Marriage",
beside = TRUE,
legend = rownames(work.gender.marriage.table))`

My data:

`structure(list(marriage = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L),    class = "factor", .Label = c("D", "M", "NM", "W")), gender = structure(c(2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L), .Label = c("F", "M"), class = "factor"), val = c(12L, 61L, 78L, 56L, 71L, 33L, 86L, 93L)), .Names = c("marriage", "gender", "val"), row.names = c(NA, -8L), class = "data.frame")`

This is the image after using the code:

 barplot(work.gender.marriage.table,main = "Gender & Marriage",
 beside = TRUE)

 legend("topright", 
        legend = rownames(work.gender.marriage.table), 
        ncol = 2,
        cex = 0.5)

Image:enter image description here

AK88
  • 2,946
  • 2
  • 12
  • 31
  • The "enter image description here" is not part of my code; ignore that. It does contain the image of my barplot if you click on it! – Natalia Khodayari Jul 03 '17 at 03:40
  • one option is to use par(xpd=TRUE) before legend() so that it appears outside the plotting area. – Edgar Santos Jul 03 '17 at 03:42
  • Hi ed_sans! Thank you for the advice; I keep getting the following error: "Error in width/2 : non-numeric argument to binary operator In addition: Warning message: In mean.default(width) : argument is not numeric or logical: returning NA" Would this be because I do not have the appropriate package? – Natalia Khodayari Jul 03 '17 at 03:45
  • 2
    You should provide a working dataset with your question. Say work.gender.marriage.table – Edgar Santos Jul 03 '17 at 03:46
  • I'm sorry, I'm not sure what to fix in my code; I thought it had a working dataset? Is there a way you can show me within my code what you mean? Thank you again! – Natalia Khodayari Jul 03 '17 at 03:55
  • 1
    If you add the data we can run the codes other wise it's just guessing. Use dput(work.gender.marriage.table) to add your data.frame – Edgar Santos Jul 03 '17 at 03:59

2 Answers2

5

Try this:

barplot(work.gender.marriage.table,main = "Gender & Marriage",
beside = TRUE)

Then add your legend as:

legend("topright", 
       legend = rownames(work.gender.marriage.table), 
       ncol = 2,
       cex = 0.5)

Based on your data:

df = structure(list(marriage = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), class = "factor", .Label = c("D", "M", "NM", "W")), gender = structure(c(2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L), .Label = c("F", "M"), class = "factor"), val = c(12L, 61L, 78L, 56L, 71L, 33L, 86L, 93L)), .Names = c("marriage", "gender", "val"), row.names = c(NA, -8L), class = "data.frame")
df


dfM <- df[which(df$gender=="M"),]
dfF <- df[which(df$gender=="F"),]
dfN <- cbind(dfM[,3], dfF[,3])
colnames(dfN) <- c("M", "F")
rownames(dfN) <- dfM$marriage
dfN

barplot(dfN, beside=T, legend.text = rownames(dfN),
        args.legend = list(x = "topleft", bty="n", cex = 0.7, ncol = 2))

enter image description here

AK88
  • 2,946
  • 2
  • 12
  • 31
  • I used " barplot(work.gender.marriage.table,main = "Gender & Marriage",beside = TRUE,legend = list(rownames(work.gender.marriage.table), (cex = 0.5) " and I would not get an error, or a change in the image, but "+"s instead of ">"s I'm sorry for the confusion! – Natalia Khodayari Jul 03 '17 at 04:01
  • AK88; I think it was close! I received one error stating: "Error in barplot.default(work.gender.marriage.table, main = "Gender & Marriage", : 'height' must be a vector or a matrix" And the graph had the same legend unmoved, but it did create a smaller legend in the top right corner with the numbers 1-8. Thank you again for your help! – Natalia Khodayari Jul 03 '17 at 04:17
  • check this part carefully `legend = rownames(work.gender.marriage.table)` – AK88 Jul 03 '17 at 04:18
  • You mean like this: barplot(work.gender.marriage.table,main = "Gender & Marriage",beside = TRUE, legend("topright"), legend = rownames(work.gender.marriage.table), ncol = 2, cex = 0.5) ? – Natalia Khodayari Jul 03 '17 at 04:28
  • No, take the `legend` outside. Just copy and paste my code :)) – AK88 Jul 03 '17 at 04:29
  • Almost! everything is perfect, except the numbers 1-8 still appear instead of the marriage information. I'm trying to add some of my dataset to this question but I'm very confused. First day in R is not going well. I'm sorry for taking your time I really appreciate your help! – Natalia Khodayari Jul 03 '17 at 04:43
  • No worries at all. Just do this `dput(work.gender.marriage.table)` and copy and paste the output to your question. – AK88 Jul 03 '17 at 04:45
  • Btw, where are you getting your data from? – AK88 Jul 03 '17 at 04:46
  • Okay I'll try that! It's from a professor for an assignment! It does not say we need to reduce the size of the legend, but if it weren't an assignment I would definitely have to. Plus R is used in my lab so might as well not do the bare min! – Natalia Khodayari Jul 03 '17 at 04:49
  • AK88 I have tried placing the output in my code, but it is not working still sadly. I might be placing it in the wrong area of my code? – Natalia Khodayari Jul 03 '17 at 04:54
  • No, you have to paste the `dput()` output here, in the body of your question so that we can see your data. – AK88 Jul 03 '17 at 04:56
  • Oh I see! Like this? structure(list(marriage = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), class = "factor", .Label = c("D", "M", "NM", "W")), gender = structure(c(2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L), .Label = c("F", "M"), class = "factor"), val = c(12L, 61L, 78L, 56L, 71L, 33L, 86L, 93L)), .Names = c("marriage", "gender", "val"), row.names = c(NA, -8L), class = "data.frame") – Natalia Khodayari Jul 03 '17 at 04:57
  • 2
    Yep. Give me a moment. – AK88 Jul 03 '17 at 04:58
  • 1
    AK88; Thank you! I updated my question with the image I received. I am not sure why our graphs differ, but I wrote down the code I used to receive this graph. I may have made a mistake. Thank you!! – Natalia Khodayari Jul 03 '17 at 06:21
  • Looks like your legend is still blocking some bars. Try this `barplot(dfN, beside=T, legend.text = rownames(dfN), args.legend = list(x = "top", bty="n", cex = 0.7, ncol = 2))` – AK88 Jul 03 '17 at 06:29
  • I see; where do I put this exactly? The areas I am inserting it gives me errors sadly! – Natalia Khodayari Jul 03 '17 at 06:34
  • Try this: `barplot(dfN, beside=T, legend.text = rownames(dfN), args.legend = list(x = "top", bty="n", cex = 0.7, ncol = 2))` – AK88 Jul 03 '17 at 06:35
  • Yes, but where do I place this code? I am not placing it in the correct area. – Natalia Khodayari Jul 03 '17 at 06:38
  • You can ignore the previous two `barplot()` and `legend()` codes and just run this code instead. – AK88 Jul 03 '17 at 06:39
  • I receive the following error: Error in barplot(dfN, beside = T, legend.text = rownames(dfN), args.legend = list(x = "top", : object 'dfN' not found – Natalia Khodayari Jul 03 '17 at 06:42
  • Maybe I am lacking a package? – Natalia Khodayari Jul 03 '17 at 06:42
  • 1
    No, you are fine. Just change `dfN` to `work.gender.marriage.table`. Everywhere. – AK88 Jul 03 '17 at 06:44
  • 1
    YESSSS IT WORKS!!! YOU'RE THE BEST!!!! Thank you so much for your patience and all of your help!! ^_^ – Natalia Khodayari Jul 03 '17 at 06:46
1

You could use ggplot2 as well.

library(ggplot2)
ggplot(work.gender.marriage.table) + 
  geom_bar(aes(y = val, x = cat), stat="identity") + facet_grid(. ~ sex)

Example data.frame:

work.gender.marriage.table <- data.frame(cat = c("D", "M", "NM", "W", "D", "M", "NM", "W"),
                                         sex = rep(c("M","F"), each = 4),
                                         val = sample(1:100,8))

enter image description here

Edgar Santos
  • 3,426
  • 2
  • 17
  • 29