WestHealth / pyvis

Python package for creating and visualizing interactive network graphs.
http://pyvis.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
964 stars 163 forks source link

google colab #49

Open willfinnigan opened 4 years ago

willfinnigan commented 4 years ago

Hi, great package! I was wondering if you had any tips for getting the graph to load in google colab. Currently, I get 'localhost refused to connect' as an error.

lambdamusic commented 4 years ago

Same here. It'd be great to have it working in Colab (ps it works if you just save to a file)

Screenshot 2019-10-21 at 22 54 00

willfinnigan commented 4 years ago

I ended up using a binder notebook to demo the stuff I was working on.

lambdamusic commented 4 years ago

the other option is to save the html file locally, open the 'files' sidebar, right click + download and then open it locally. laborious but it works..

masdeseiscaracteres commented 4 years ago

The problem is the files for the underlying library vis.js are being linked from the web at the visualization time. This poses a limitation when using the library in environments with no internet connection. It would be great to offer the user an option to specify the location of the required files or, even better, embed the required files into the library. Right know it is possible to patch the template.html file but that should not be the way to go. Is there any licensing reason for not doing so?

lambdamusic commented 4 years ago

Looks like vis.js is dual licensed, Apache 2.0 and MIT.
PyVis seems to be BSD.

lambdamusic commented 4 years ago

@masdeseiscaracteres do you think that it'd be enough to add a local copy of visjs in the same folder as the html template, and then updating the link?

masdeseiscaracteres commented 4 years ago

I don't think so. That's the first thing I tried and failed miserably.

It fails because when you run

g.show('example.html')

a file called example.html is created in your working directory based on the HTML template. Your browser needs to be able to get to the location where you have your visjs files stored based on the link in that HTML file.

What I did so far was embedding the whole visjs into the HTML template so that no links are required. I guess there has to be a cleaner way to do it.

masdeseiscaracteres commented 4 years ago

BTW, this is how plotly.py is doing to allow the user to create plots that work offline: https://github.com/plotly/plotly.py/blob/master/packages/python/plotly/plotly/offline/offline.py#L458-L492

lambdamusic commented 4 years ago

that makes sense and prob the way to go. I'm overstretched at the moment but can't wait to have time to hack something together ...

lambdamusic commented 4 years ago

I finally got it to work. I did two things a) modify the html template so that all JS is included. b) create a custom version of pyvis.Network so that the template path points at the new template and the show method checks if we are in Colab and if so it return a IPython.display.HTML object instead of an IFrame.

This has been implemented as part of another library I'm working on (dimcli), but the gist of it is generic enough:

try:
    from google.colab import files
    COLAB_ENV = True
except:
    COLAB_ENV = False

class NetworkViz(PyvisNetwork):
    """Extend PyVis class so that we can use a modified template that works in Colab. 
    """

    def __init__(self,
                 height="500px",
                 width="500px",
                 directed=False,
                 notebook=False,
                 bgcolor="#ffffff",
                 font_color=False,
                 layout=None):
        # call super class init
        PyvisNetwork.__init__(self, 
                              height, 
                              width,
                              directed,
                              notebook,
                              bgcolor,
                              font_color,
                              layout)
        # override template location - update as per installation
        self.path =  os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'templates/pyvis_inline.html'))

    # fun copied from pyvis to skip imports
    def check_html(self, name):
        """
        Given a name of graph to save or write, check if it is of valid syntax
        :param: name: the name to check
        :type name: str
        """
        assert len(name.split(".")) >= 2, "invalid file type for %s" % name
        assert name.split(
            ".")[-1] == "html", "%s is not a valid html file" % name

    # fun extended for colab
    def show(self, name):
        """
        Writes a static HTML file and saves it locally before opening.
        :param: name: the name of the html file to save as
        :type name: str
        """
        self.check_html(name)
        if self.template is not None:
            if not COLAB_ENV: 
                # write file and return IFrame
                return self.write_html(name, notebook=True)
            else:
                # write file and return HTML
                self.write_html(name, notebook=True)
                return IPython.display.HTML(filename=name)
        else:
            self.write_html(name)
            webbrowser.open(name)

See it in action in this Colab notebook https://drive.google.com/file/d/188vea7vRsLjWvHd0RBnufXOatt43uBcC/view?usp=sharing

PS it'd be nice if @boludo00 or one of the maintainers would consider changing pyvis so that Google Colab is supported by default...

edsu commented 3 years ago

I don't know if something has changed in the last couple of years but it looks like on Colab you just need to perform an extra step to display the generated HTML:


from IPython.core.display import display, HTML

g.show('network.html')
display(HTML('network.html'))
apodgorny commented 1 year ago

The problem is in the html file that it generates:

<!-- < link rel="stylesheet" href="../node_modules/vis/dist/vis.min.css" type="text/css" />
<script type="text/javascript" src="../node_modules/vis/dist/vis.js"> </script>-->

It fails with 'vis is not defined' because, as you see, vis library is included with a relative path, which is, obviously, is missing in the notebooks. Not to mention, that it is commented out, lol.

The fix would be to include it from cdn, like the rest of js in the file. WHOEVER HAS ACCESS TO THE CODE -> FIX IT!!!

bimal-gajera commented 11 months ago

I don't know if something has changed in the last couple of years but it looks like on Colab you just need to perform an extra step to display the generated HTML:

from IPython.core.display import display, HTML

g.show('network.html')
display(HTML('network.html'))
bimal-gajera commented 11 months ago

works for me

pfyeh1 commented 5 months ago

I got it to work by passing in cdn_resources = 'remote'

net = Network(notebook = True, cdn_resources = 'remote')

wrgr commented 5 months ago

Possibly helpful to others - as of today, this works with default packages and versions, building on this thread and others.

`

pyvis 0.3.2

!pip install pyvis

from pyvis.network import Network import networkx as nx from IPython.core.display import display, HTML net = Network(notebook = True, cdn_resources = 'in_line')

build graph

nx_graph = nx.cycle_graph(10) nx_graph.nodes[1]['title'] = 'Number 1' nx_graph.nodes[1]['group'] = 1 nx_graph.nodes[3]['title'] = 'I belong to a different group!' nx_graph.nodes[3]['group'] = 10 nx_graph.add_node(20, size=20, title='couple', group=2) nx_graph.add_node(21, size=15, title='couple', group=2) nx_graph.add_edge(20, 21, weight=5) nx_graph.add_node(25, size=25, label='lonely', title='lonely node', group=3)

populates the nodes and edges data structures

net.from_nx(nx_graph) net.show('nx.html') display(HTML('nx.html')) `