konstantint / matplotlib-venn

Area-weighted venn-diagrams for Python/matplotlib
MIT License
496 stars 67 forks source link

Percentages in venn diagramms #8

Closed fgypas closed 7 years ago

fgypas commented 10 years ago

Hello

I want to show in the figure the percentages of intersection, apart from the number. Is that possible?

Kind regards Foivos

konstantint commented 10 years ago

It is not built in, but you are free to modify labels to your liking. E.g.:

v = venn2((1,2,3))
v.get_label_by_id('11').set_text('%0.0f%%' % (2.0*100/6))

I am not sure whether this should be part of standard functionality, as it might not always be obvious as to percentage of what should be shown.

fgypas commented 10 years ago

Well an option to choose between percentages (based on the unique union) and total number would be nice. Well I implemented it with labels, as you mentioned. Thanks for your the reply and help.

konstantint commented 10 years ago

I think perhaps a "number formatter" could be a more generic option, e.g. (... labelformat="%0.2%%"). When combined with manual rescaling of the numbers it would provide a way of displaying percentages in the desired fashion.

.. although I'm still not sure it is worth it (I'm just being careful because adding any convenience feature like that may turn out to be a burden for purposes of backward compatibility at some point in the future).

jamartinh commented 9 years ago

Hello, how about using a simple optional keyword arguments as labelstyle and a set of options for this parameter?

konstantint commented 9 years ago

Let me repeat, that the problem with adding a set of options for each potential use case is that it eventually leads to bloated code that becomes near impossible to support in a backwards-compatible manner. I'm adding percentages today, tomorrow someone asks for special parameters for shifting circles around, next month we think we need a special parameter for capitalizing titles, etc. You could disagree with me, but I feel that a good function should provide the smallest possible functionality that makes sense together. Anything else, if it is unrelated to the point of being packageable into a separate abstraction, be it a module/function or a package, should be packaged as a separate abstraction.

As I noted, I would agree, that "number_formatter" is on the edge of something which might be present in the parameter list of venn. However, I still did not add it because, firstly I am using this library actively and so far never had the need, secondly, there do not seem to be much activity in this ticket either, thirdly, there is a simple way to implement it as a separate function, and, as I mentioned above, in my world this is a very strong indicator in favor of not rushing to integrate it into the function.

Namely, at the moment, setting any format for your labels is as simple as:

def reformat_labels_to_my_taste(v):
    for sl in v.subset_labels:
        if sl is not None:
            sl.set_text('New: ' + sl.get_text())

v = venn3([set([1,2,3]), set([2,3,4]), set([5,6,7])])
reformat_labels_to_my_taste(v)

Which, among other things, gives you all the freedom to do whatever you like to the labels without having to worry that your code breaks in a year due to some random decision of mine regarding the changes to formatting or something (say, tonight I'm all in the mood of having label_format="%f", but in a month I feel that this was stupid and change it to label_format=lambda x: "%f" % x instead, or the like.

I do think that some standard diagram utility functions might be implemented somewhere in the util package eventually, though. But so far I'm delaying this as long as people are not actively demanding it nor offering something extremely constructive, due to the reasons described above.

konstantint commented 7 years ago

PR#28 closes this issue. Now there's a subset_label_formatter parameter.