igraph / python-igraph

Python interface for igraph
GNU General Public License v2.0
1.28k stars 247 forks source link

Ease of use in various environments #392

Open szhorvat opened 3 years ago

szhorvat commented 3 years ago

Accessibility and ease of use is an important goal for igraph. I would love to see it being easy to use in various popular interactive environments. I reached out to https://cocalc.com to ask that python-igraph be a default package. They were supportive and it will be included in the next release. Plotting works fine.

Another very popular such environment is Google Colab https://colab.research.google.com/ I cannot get plotting working there, even after successfully installing pycairo.

We should look into which environments people might use python-igraph, and either work with the developer of that environment to make it work, or provide instructions on how to make igraph work.

@iosonofabio Is this something you'd be interested in looking into, in particular getting plotting working in Google Colab?

szhorvat commented 3 years ago

For the record, this is what I tried:

!apt install libcairo-dev
!pip install pycairo
!pip install python-igraph
import igraph as ig
g=ig.Graph.Erdos_Renyi(n=100,m=200)
ig.plot(g)

It gives me a very unhelpful AttributeError: plotting not available, with no hints on where to look for solutions. I would consider this a user experience bug.

ntamas commented 3 years ago

The AttributeError: plotting not available error appears when import cairo fails with an ImportError; we catch the exception and replace cairo with a fake module that raises an AttributeError for every single attribute access. Note that from inside Python, it is hard to distinguish between a missing pycairo library and a pycairo library that fails to import for other reasons.

For sake of completeness, I should mention that we also try cairocffi, an alternative Cairo frontend that is API-compatible with cairo itself.

I tried to reproduce the issue, but the snippet that you sent works just fine for me; here is a Colab notebook where I successfully managed to plot a graph:

https://colab.research.google.com/drive/1Lkywky1AKEmDcW235nD4EvopTt_gCcZi?usp=sharing

ntamas commented 3 years ago

Anyway, we can try improving the plotting not available error message, but there's only so much we can put into an exception message (some environments might truncate the string). We can try something like `Plotting not available. Try running "pip install cairocffi" or "pip install cairo" if you haven't done so yet.", but as you can see, this message would not have been very helpful in your case.

Another option is to put a permalink in the message that leads the user to the appropriate chapter in the Python tutorial, where we can add more detailed instructions.

szhorvat commented 3 years ago

You are right, it works in Google Colab. I did not realize that closing and re-opening the notebook in Colab does not necessarily restart the kernel. That's why it failed.

iosonofabio commented 3 years ago

Part of the reason behind the matplotlib PR was that mpl works in all these situations: the notebook/colab folks make sure of that, so that makes our life easier.

I'm unsure how you guys feel about it, but I would conceive switching entirely to mpl as default within the next year or so

szhorvat commented 3 years ago

There is a lot of value in going with the standard. It helps interoperability. If it reaches feature parity with the Cairo backend, and there is no major performance downside (I never measured!), it sounds like a good idea to make it the default.

It would be also nice to add some examples / tutorial pages that show off what you can do with the matplotlib backend that you couldn't easily do with Cairo, such as combining with other plots and other graphics elements.

So far the one important lacking feature I noticed is support for multi edges, #395

iosonofabio commented 3 years ago

395 is closed now, and I just added some info to the visualization docs about at least two common situations where matplotlib is useful. Shall we close this issue then?

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

iosonofabio commented 3 years ago

The plotting PR brings mpl and plotly to parity with Cairo. I expect that to take help with colab, data bricks, notebook, jupyterlab, etc.

ntamas commented 1 year ago

For the record, I tried this again on Google Colab with the following script:

!pip install python-igraph
import igraph as ig
g = ig.Graph.Erdos_Renyi(n=100, m=200)
ig.plot(g)

It still complains about Cairo as that one is the default plotting backend. matplotlib is installed in Google Colab by default, so I was wondering whether we should try to be smart and select a plotting backend based on what's available (while still preferring Cairo for the time being if the user has both, for sake of backwards compatibility). This would make igraph much easier to use in notebook environments with matplotlib; right now the user would need to realize that there are actually multiple plotting backends and that the backend can be switched to matplotlib.

iosonofabio commented 1 year ago

What about:

If you don't have Cairo but you have matplotlib and your config is set to Cairo, we print a warning message immediately telling the user how to set mpl as backend?

ntamas commented 1 year ago

I was wondering how we could test for the presence of matplotlib without importing it. I'm a bit worried that importing matplotlib directly has side effects like the initialization of Matplotlib's plotting backends, which might take too much time and might do stuff that we don't want (e.g., starting an X server on macOS?).

szhorvat commented 1 year ago

Loading matplotlib also breaks checking for leaks with LeakSanitizer.

ntamas commented 1 year ago

Maybe this?

import importlib
spec = importlib.util.find_spec("matplotlib")
found = spec is not None
iosonofabio commented 1 year ago

yes:

https://stackoverflow.com/questions/14050281/how-to-check-if-a-python-module-exists-without-importing-it