Phlya / adjustText

A small library for automatically adjustment of text position in matplotlib plots to minimize overlaps.
https://adjusttext.readthedocs.io/
MIT License
1.5k stars 87 forks source link

Backends to use in a multithreaded environment #157

Closed paulin-mipt closed 4 months ago

paulin-mipt commented 1 year ago

Hello and thank you for this very useful package!

As I understood, some backends in matplotlib don't work well in frameworks using threading, like Django. It can be solved by selecting a different backend (e.g. matplotlib.use("Agg")).

But "Agg" backend doesn't work with adjust Text - all labels just go to (0, 0) point. Can you please list specifically which backends are supported/not supported with adjustText, and if possible - which ones are compatible with threading.

Environments of my particular interest are MacOS and Debian.

Phlya commented 1 year ago

Hi Paulin,

This is interesting. I thought adjustText should work with all backends. I don't know how to answer your question, it requires some experimentation... Can you provide an example of code that doesn't work with Agg?

Texts going to (0,0) is an indication that the axes limits are not set up prior to calling adjust_text. Have you tried calling plt.show() to enforce the whole draw cycle? Generally, this has been a recurring issue in non-trivial situations, but I thought finally it was all working. Could you also try the branch from this PR to see whether it fixes your issue? https://github.com/Phlya/adjustText/pull/147

paulin-mipt commented 1 year ago

Thank you for swift response Ilya! I've tried the fix and it didn't change anything unfortunately. I've also tried plt.show() (I was using plt.savefig() before) and it didn't help too

I'll try making up a minimal example later today. I'm sure that I'm setting the axes limits though, I've seen this suggestion in other issues. Because my axes limits don't start from (0, 0) I'm sure that it's being applied, because it's obvious in my case.

paulin-mipt commented 1 year ago

Hi again Ilya, I'm very sorry because my initial question was misleading. My problem was something totally unrelated - one line missing from the code.

But I still can't explain to myself, why exactly it had this effect. It appears that if I only draw labels without any plot, they start misbehaving - please see my example below. Maybe I've discovered another bug (or that's WAI?).

import matplotlib.pyplot as plt
from adjustText import adjust_text

fig, ax = plt.subplots(figsize=(9, 9))
x_label_limits = (-0.5, 2.5)
y_label_limits = (-0.5, 2.5)

x_data = [0, 1, 2]
y_data = [0, 1, 2]
disease_labels = ["One", "Two", "Three"]

# BUG: if we comment out the following line, adjust_text starts behaving weirdly
sc = sns.scatterplot(x=x_data, y=y_data, ax=ax)

texts = []
for x, y, disease_label in zip(x_data, y_data, disease_labels):
    text = plt.text(x, y, disease_label, ha='center', va='center', fontsize=10)
    texts.append(text)

adjust_text(texts, ax=ax, expand_text=(1.02, 1.02))

ax.set_xlim(*x_label_limits)
ax.set_ylim(*y_label_limits)

plt.show()

With the scatter plot drawing it looks like this: https://ibb.co/TLPbn6H Without the scatter plot - something unexpected happens: https://ibb.co/xYN08v8

Phlya commented 1 year ago

Set the axes limits before calling adjust_text, then it should work as expected. scatterplot sets axes limits to something reasonable, and that's why texts are adjusted correctly.