gaospecial / ggVennDiagram

A 'ggplot2' implement of Venn Diagram.
https://gaospecial.github.io/ggVennDiagram/
GNU General Public License v3.0
284 stars 38 forks source link

Spacing between setEdge and setLabel #71

Open SamThilmany opened 3 months ago

SamThilmany commented 3 months ago

Hello Gao,

Thank you for your work on this fantastic package!

In many ggVennDiagram examples, set labels are single characters (e.g., A, B, C, D). However, I need to use longer labels, which often overlap the set edges or intrude into the polygons.

While examining the code, I noticed that label positioning is handled by the fancy_**_**_label() functions, defined in shapeMageR, where the label positions seem to be hard-coded.

Is there a way to increase the spacing between the set edge and the label I might have missed? If not, would adding this feature for further customization be feasible?

Thank you for your support and this excellent package!

gaospecial commented 3 months ago

This is really a problem, but still have no simple solution.

In manual, I gave an example to expand the grid for show labels https://gaospecial.github.io/ggVennDiagram/articles/using-ggVennDiagram.html#long-category-names. But this should not be your question here.

For myself, I sometimes export figure and then edit it in other software like PowerPoint or Adobe Illustrator. For instance, export with export::graph2ppt().

There is also another solution using annotate() function in ggplot2. Just set category labels to empty string and use annotate() to add them one by one. Please refer to ?ggplot2::annotate for more information.

SamThilmany commented 3 months ago

I found a "quick fix" that works for my case. Perhaps a similar approach could be adapted to create a more dynamic solution.

I was plotting 4D Venn diagrams, and the labels for the two "center" ellipses were too close to the ellipses themselves due to their angle and shape.

To address this, I duplicated my data list to keep a version with the names and created another list where I removed the names:

data_no_names <- data
names(data_no_names) <- c(rep("", length(data)))

Next, I applied the Venn() and process_data() functions to both data lists:

venn_no_names <- ggVennDiagram::Venn(data_no_names)
venn <- ggVennDiagram::Venn(data)

data_no_names <- ggVennDiagram::process_data(venn_no_names)
data <- ggVennDiagram::process_data(venn)

For the plot_venn() function, I used the data_no_names list to remove the setLabels from the initial plot. I then added the labels manually with geom_text, using your venn_setlabel() function but altering the x values:

plot <- ggVennDiagram::plot_venn(data_no_names) +
    geom_text(
        aes(
            ifelse(X < 0.5, X - (X * 0.4), X + ((1 - X) * 0.4)), 
            Y, 
            label = name
        ),
        data = ggVennDiagram::venn_setlabel(data)
    )

The venn_setlabel() function sets the x and y coordinates as follows, as defined in the shapeMageR package:

x = c(0.08, 0.26, 0.71, 0.93),  # x coordinates
y = c(0.78, 0.86, 0.85, 0.78)   # y coordinates

These are relative coordinates, with the center of the 4D plot at 0.5. To shift the two center coordinates (0.26, 0.71) more than the outer ones (0.08, 0.93), I used the value itself multiplied by an offset. Since the first two coordinates need to be shifted left and the last two right, I applied a conditional check to subtract the calculated value for the first two coordinates and add it for the last two.

This adjustment creates more space between the setLabel and the setEdge.