Python matplotlib color empty

68 Views Asked by At

I have 2 Venn diagramas to draw. The peculiarity is there are 3 sets per diagram, and one of the set encompasses all the others. Therefore, I get color blending which makes it a bit uneasy to read the diagram (because you have to know than green + yellow = blabla). Therefore I decided to modigy the code, so that the circles would be transparent, only their circumferences should be visible and have the right color code.

Unfortunately, in my output, the circumferences are not colored according to the legend and line parts disappear when another circle overlap there, here is the code

import matplotlib as mpl
from matplotlib_venn import venn3
import matplotlib.pyplot as plt
from matplotlib import colormaps

def plot_venn(set1, set2, set3, title, filename=None):
    plt.figure()
    venn = venn3([set1, set2, set3], set_labels=('Pileup', 'Align', 'Merge'))

    # Sample colors from the Viridis colormap
    viridis = mpl.colormaps['viridis']
    colors = [viridis(0.3), viridis(0.5), viridis(0.7)]  # Select distinct colors

    # Apply colors only to the circumferences of the Venn diagram
    for idx, subset_id in enumerate(['100', '010', '001']):
        patch = venn.get_patch_by_id(subset_id)
        if patch:
            patch.set_edgecolor(colors[idx])  # Color the edge
            patch.set_facecolor('none')       # Make the face transparent
            patch.set_linewidth(2)            # Set the line width

    # Ensure all intersections are transparent
    for subset_id in ['110', '101', '011', '111']:
        patch = venn.get_patch_by_id(subset_id)
        if patch:
            patch.set_facecolor('none')  # Make intersections transparent

    # Change the color of the subset labels (numbers) to white
    for label in venn.subset_labels:
        if label is not None:
            label.set_color('white')

    # Create a custom legend
    for label, color in zip(('Pileup', 'Align', 'Merge'), colors): #I am not sure of mlmy zip function here
        plt.scatter([], [], color=color, label=label)
    plt.legend(frameon=False, bbox_to_anchor=(1.05, 1))

    plt.title(title)

    if filename:
        plt.savefig(filename, format='svg')

    plt.show()
    plt.close()

plot_venn(set_pileup_guppy, set_align_guppy, set_merge_guppy, 'Venn Diagram for Guppy DataFrames', 'guppy_venn_diagram.svg')
plot_venn(set_pileup_hifi, set_align_hifi, set_merge_hifi, 'Venn Diagram for HiFi DataFrames', 'hifi_venn_diagram.svg')

And here is one output: output

As you see, the circumference of the sets all have the same color Also, 2 sets, align and merge are mostly identical. What I would need is a kinf of concentric rings, actually.

I wonder if this is actually doable? Or if I shouldn't simply modify the SVG in Inkscape.

Any suggestion would be welcome. The underlying data have nothing special, just sets of intersection. You will also see my doubts commented in the code.

Thanks a lot everyone

Cheers

0

There are 0 best solutions below