A great explanation of things as always Nikolay; I really appreciate the effort you are putting in to providing these sorts of explanations. A lot of the complexity in the UMAP python code-base amounts to various things to gain efficiency for very large datasets, and that can certainly obfuscate the underlying ideas somewhat.
Of note, if you are interested in forcing greater separation among things (such as you gained with the alternative symmetrization approach) you can look at the (currently badly named) ``set_op_mix_ratio`` parameter in the python implementation of UMAP. This interpolates between union (1.0, the default) and intersection (0.0). In general the union will retain a lot more connectivity, while the intersection tends to shatter things into small pieces. This means very low values (in the order of 0.1) are good if you want to do outlier detection, for example (you’ll lose a lot of global structure, but outliers will be better preserved). A value of 0.5 (midway between union and intersection) will essentially result in your symmetrization.
That parameter is not especially well documented, but if it is useful for various use cases (such as you display here), I will endeavour to provide it a more useful name and some better documentation.