# Visualize binary trait distribution in two groups

I have just two groups with the certain (not equal to each other) numbers of the trait observations within each group. The trait has only two levels- 0 and 1 (i.e. this trait is binary). For example: we have case and control groups. There are 280 infected (1 state) and 20 uninfected (0 state of the trait) plants (300 totally) in control group. In case group we see 250 uninfected plants (0 state of the trait) and 80 infected ones (1 state) (330 totally). I'd like to show that proportions of infected/uninfected plants are different in these groups. My solution in R base was (just toy example):

case=seq(0,0,,length.out = 50)
control=seq(1,1,length.out = 50)
boxplot(case,control,names = c('case','control'))


So, in many cases the plots look like:

I'm wondering if there is more elegant solution. Any help would be highly appreciated.

• Describe the variables and their values and what you are trying to show. Jan 14, 2019 at 7:55
• Your question seems quite irrelevant to what you want to do, which is explained much better in your comment. So, please edit the question to include the material in the comment. Also, a box plot showing that all cases are alike in being cases and all controls are alike in being controls is not obviously useful for any purpose, except for verifying that all values are 0 or 1. Jan 15, 2019 at 14:37
• I will emphasise my previous comment. What is key here on CV to good threads is not just whether the OP gets an answer to their question but also whether the thread will help others in future. The question remains hard to understand until the comments are read. Jan 16, 2019 at 10:52

As others have suggested, a mosaic plot is a clear possibility here, allowing portrayal not only of probabilities of case or control and uninfected or infected but also of absolute numbers.

This was drawn in Stata (complete code below for anyone interested, but you need to install spineplot). Graphs as good or better should be easily possible in your own favourite software. If not, you need new favourite software. Showing the absolute frequencies as text label is a little unusual for this kind of graph, but clearly it is optional and the results are readable for a 2 x 2 set-up. Reversing the order of infected and uninfected (or of case and control) is also possible.

clear
input byte case byte infected float frequency
0 0  20
0 1 280
1 0 250
1 1  80
end
label values case case
label def case 0 "control" 1 "case"
label values infected infected
label def infected 0 "uninfected" 1 "infected"

set scheme s1color
spineplot infected case [fw=freq], bar1(color(blue*0.6)) bar2(color(red*0.6)) ///
text(freq, mlabsize(*1.5)) ytitle("", axis(2)) xtitle("", axis(2))  xtitle("", axis(1))

• Many thanks for your reply. Could your a bit clarify for me please? What axes labels mean? Are they just percentages? Why they are different for two axes and how i can interpret it? Jan 15, 2019 at 22:00
• They certainly aren't percent scales. They are cumulative probability scales going from 0 to 1. There isn't a good reason for the labels being different. That's a quirk in the code. Jan 16, 2019 at 7:33
• I've corrected the plot. There was a small bug in my code. The public version of the code will be fixed in due course. Sorry about the confusion. Jan 16, 2019 at 9:23

In your toy example, all the cases have trait = 0 and all the controls have trait = 1. That's probably not what you want. If every observation is either 0 or 1 then you only need to plot one of them, since the other will be determined.

So you could use a simple bar plot of trait = 0 for the two groups.

If your trait had multiple levels, I would consider a mosaic plot. If you wanted to stick with bar plots, I would not use stacked bars; William Cleveland has shown that these are not very good representations. I'd use separate bars for each trait.

Another possibility (probably better than bars) is a Cleveland dot plot.

• Thank you so much for detailed response. I'm curious, what are the most crucial differences of mosaic plot from stacked barplot? From the examples i can see here they look pretty similar. Jan 15, 2019 at 21:46
• The mosaic plot uses width as well as height to convey frequency (probability) on both scales. That is visible even with your data with 300 and 330 in control and case groups. Jan 16, 2019 at 9:25

You could either use a dotplot or bar plot showing the % values that are one (or zero). Or you could use a stacked bar plot with two bars, one for each treatment. Within each bar, use two colours for the % of values that are zero and one.

Here's an example I found online, although it has more than 2 groups (source: https://python-graph-gallery.com):

And here's a tutorial that shows how to make them with R & ggplot2: https://rstudio-pubs-static.s3.amazonaws.com/329677_8f579b9e46284caeb9d3a72b7fdb7ac3.html