2

I'm using the VennDiagram R package to try to generate a neatly formatted diagram comparing two groups. I have successfully used this package in the past to compare relatively similarly-sized groups. However, now I'm comparing groups that have significantly different sizes (# of unique elements in the first group is ~3,600, # of unique elements in the second group is ~60, and # of overlapping elements is ~80).

The appearance of my current Venn diagram is that the group with the larger # of elements has this value displayed within its circle, but the labels for the intersection of the two groups and the unique elements in the second group are too large to be included in those regions of the diagram, so instead, they are displayed outside of the diagram with a line connecting them to the associated region. I don't like the appearance of this, and would like to reduce the size of all 3 labels so that they can be displayed within their respective regions of the diagram. However, after having reviewed the associated documentation/examples and publication (Chen & Boutros 2011), I'm still not clear about how to do this. (For example, I see parameters that permit the specification of font size of the figure title and subtitle, but I don't see where the labels' font size can be specified...)

I have attempted workarounds such as trying to make the labels invisible so that I can manually add them in a separate application, but this doesn't seem to be an option...

Any suggestions for how I can reduce the font size of my labels and specify that these labels appear within the regions of the diagram rather than outside of the diagram, will be appreciated. Thanks!


Update: As requested below, I am providing my example code:

library(VennDiagram);
library(grid);

Data <- read.csv('ExampleDataset_VennDiagram.csv')

Dataset1 <- Data[,1]
Dataset2 <- Data[,2]


    MyVennDiagram <- venn.diagram(
    x = list(
            A = Dataset1,
            B = Dataset2
        ),
    main = "",
    main.cex = NULL,
    filename = NULL,
    lwd = 2,
    fill = c("blue", "green"),
    alpha = 0.75,
    label.col = "black",
    cex=c(2,2,2),
    fontfamily = "sansserif",
    fontface = "bold",
    cat.col = c("blue", "green"),
    cat.cex = 0,
    cat.fontfamily = "serif",
    cat.fontface = "bold",
    cat.dist = c(0.05, 0.05),
    cat.pos = c(-20, 14),
    );

grid.newpage()
grid.draw(MyVennDiagram)

Update: Based on missuse's suggestion below, using ext.text = FALSE works perfectly!

Thanks to everyone who contributed to this thread.

The eulerr library appears to generate nice-looking diagrams, and will definitely be a resource I use in the future -- thanks for sharing.

Bob Loblaw
  • 127
  • 2
  • 10
  • 1
    does `cex` parameter change the labels that you want? – user20650 Oct 29 '17 at 14:55
  • Thanks for your response, user20650; I have played with the cex parameter, which is supposed to specify the size of the areas' labels; I've tested a number of variations including the following; however, so far, none of them has worked to modify the font sizes or positions of the labels: cex = 0 cex = 1 [default value had been 4] main.cex = 0 main.cex = NULL cat.default.pos = "inner" cex.prop = NULL – Bob Loblaw Oct 29 '17 at 15:27
  • 1
    can you add a small example to your question please - cex changes labels for me (labels for the area counts) (for example , using the plot [here](https://stackoverflow.com/questions/25019794/venn-diagram-with-item-labels/25027009#25027009) adding `cex=c(1,3,5)` to the `venn.diagram` function changes label sizes.) – user20650 Oct 29 '17 at 15:36
  • I added my code to my OP; what is strange is that it doesn't seem to matter how I play with the cex or other parameters -- none of these produces an update in the diagram, which makes me wonder whether there is some more fundamental issue at play here... – Bob Loblaw Oct 29 '17 at 15:47
  • Thanks for wanting to provide input, missuse -- during my process of preparing some example data and my image, you provided the solution I needed! Using ext.text = FALSE is exactly what I needed, and now my diagram looks perfect! Thanks!! – Bob Loblaw Oct 29 '17 at 16:32
  • 1
    updated my answer with an additional library you could check out. – missuse Oct 29 '17 at 16:35
  • Excellent, thanks -- that library looks very helpful. – Bob Loblaw Oct 29 '17 at 16:53

1 Answers1

4

A possible solution to this is to avoid using euler diagrams.

To illustrate your problem here is some data:

  A = sample(1:1000, 500, replace = T)
  B = sample(1:10000, 50)

Here is the diagram obtained by

 library(VennDiagram);
 library(grid)

 MyVennDiagram = venn.diagram(
    x = list(
      A = A,
      B = B
    ),
    main = "",
    main.cex = NULL,
    filename = NULL,
    lwd = 2,
    fill = c("cornflowerblue", "pink"),
    alpha = 0.75,
    label.col = "black",
    cex=c(2,2,2),
    fontface = "plain",
    cat.col = c("cornflowerblue", "pink"),
    cat.cex = 0,
    cat.fontfamily = "serif",
    cat.fontface = "plain",
    cat.dist = c(0.05, 0.05),
    cat.pos = c(-20, 14),
    cat.default.pos = "text",
  )

  grid.newpage()
  grid.draw(MyVennDiagram)

enter image description here

by avoiding scaling of the circles with scaled = FALSE

  MyVennDiagram = venn.diagram(
    x = list(
      A = A,
      B = B
    ),
    main = "",
    main.cex = NULL,
    filename = NULL,
    lwd = 2,
    fill = c("cornflowerblue", "pink"),
    alpha = 0.75,
    label.col = "black",
    cex=c(2,2,2),
    fontface = "plain",
    cat.col = c("cornflowerblue", "pink"),
    cat.cex = 0,
    cat.fontfamily = "serif",
    cat.fontface = "plain",
    cat.dist = c(0.05, 0.05),
    cat.pos = c(-20, 14),
    cat.default.pos = "text",
    scaled = FALSE
  )

  grid.newpage()
  grid.draw(MyVennDiagram)

enter image description here

As per user20650 suggestion the best option is to use ext.text=FALSE in the original call:

enter image description here

Also check library(eulerr) it accepts a bit different input, here is an illustration:

library(eulerr)
library(tidyverse)
data.frame(dat = unique(c(A, B))) %>%
  mutate(A = dat %in% A,
         B = dat %in% B) %>%
  select(A, B) %>%
  euler() %>%
  eulerr:::plot.euler(counts = T)

enter image description here

As per user20650 comment acceptable input is also:

plot(euler(setNames(list(unique(A),unique(B)), c("A", "B"))), counts=TRUE)

missuse
  • 19,056
  • 3
  • 25
  • 47