Use networkx to draw the flow with the connections among the nodes and
        the status of the tasks.

        Args:
            mode: `networkx` to show connections, `status` to group tasks by status.
            with_edge_labels: True to draw edge labels.
            ax: matplotlib :class:`Axes` or None if a new figure should be created.
            arrows: if True draw arrowheads.
            node_size: By default, the size of the node is proportional to the number of cores used.
            node_label: By default, the task class is used to label node.
            layout_type: Get positions for all nodes using `layout_type`. e.g. pos = nx.spring_layout(g)

        .. warning::

            Requires networkx package.

def plot_networkx(self, mode="network", with_edge_labels=False, ax=None, arrows=False,
                      node_size="num_cores", node_label="name_class", layout_type="spring", **kwargs):
        """
        Use networkx to draw the flow with the connections among the nodes and
        the status of the tasks.

        Args:
            mode: `networkx` to show connections, `status` to group tasks by status.
            with_edge_labels: True to draw edge labels.
            ax: matplotlib :class:`Axes` or None if a new figure should be created.
            arrows: if True draw arrowheads.
            node_size: By default, the size of the node is proportional to the number of cores used.
            node_label: By default, the task class is used to label node.
            layout_type: Get positions for all nodes using `layout_type`. e.g. pos = nx.spring_layout(g)

        .. warning::

            Requires networkx package.
        """
        self.allocate()

        # Build the graph
        import networkx as nx
        g = nx.Graph() if not arrows else nx.DiGraph()
        edge_labels = {}
        for task in self.iflat_tasks():
            g.add_node(task, name=task.name)
            for child in task.get_children():
                g.add_edge(task, child)
                # TODO: Add getters! What about locked nodes!
                i = [dep.node for dep in child.deps].index(task)
                edge_labels[(task, child)] = " ".join(child.deps[i].exts)

            filedeps = [d for d in task.deps if d.node.is_file]
            for d in filedeps:
                #print(d.node, d.exts)
                g.add_node(d.node, name="%s (%s)" % (d.node.basename, d.node.node_id))
                g.add_edge(d.node, task)
                edge_labels[(d.node, task)] = "+".join(d.exts)

        # This part is needed if we have a work that produces output used by other nodes.
        for work in self:
            children = work.get_children()
            if not children:
                continue
            g.add_node(work, name=work.name)
            for task in work:
                g.add_edge(task, work)
                edge_labels[(task, work)] = "all_ok "
            for child in children:
                #print(child)
                g.add_edge(work, child)
                i = [dep.node for dep in child.deps].index(work)
                edge_labels[(work, child)] = "+".join(child.deps[i].exts)

        # Get positions for all nodes using layout_type.
        # e.g. pos = nx.spring_layout(g)
        pos = getattr(nx, layout_type + "_layout")(g)

        # Select function used to compute the size of the node
        def make_node_size(node):
            if node.is_task:
                return 300 * node.manager.num_cores
            else:
                return 600

        # Function used to build the label
        def make_node_label(node):
            if node_label == "name_class":
                if node.is_file:
                    return "%s\n(%s)" % (node.basename, node.node_id)
                else:
                    return (node.pos_str + "\n" + node.__class__.__name__
                            if hasattr(node, "pos_str") else str(node))
            else:
                raise NotImplementedError("node_label: %s" % str(node_label))

        labels = {node: make_node_label(node) for node in g.nodes()}
        ax, fig, plt = get_ax_fig_plt(ax=ax)

        # Select plot type.
        if mode == "network":
            nx.draw_networkx(g, pos, labels=labels,
                             node_color=[node.color_rgb for node in g.nodes()],
                             node_size=[make_node_size(node) for node in g.nodes()],
                             width=1, style="dotted", with_labels=True, arrows=arrows, ax=ax)

            # Draw edge labels
            if with_edge_labels:
                nx.draw_networkx_edge_labels(g, pos, edge_labels=edge_labels, ax=ax)

        elif mode == "status":
            # Group tasks by status (only tasks are show here).
            for status in self.ALL_STATUS:
                tasks = list(self.iflat_tasks(status=status))

                # Draw nodes (color is given by status)
                node_color = status.color_opts["color"]
                if node_color is None: node_color = "black"
                #print("num nodes %s with node_color %s" % (len(tasks), node_color))

                nx.draw_networkx_nodes(g, pos,
                                       nodelist=tasks,
                                       node_color=node_color,
                                       node_size=[make_node_size(task) for task in tasks],
                                       alpha=0.5, ax=ax
                                       #label=str(status),
                                       )
            # Draw edges.
            nx.draw_networkx_edges(g, pos, width=2.0, alpha=0.5, arrows=arrows, ax=ax) # edge_color='r')

            # Draw labels
            nx.draw_networkx_labels(g, pos, labels, font_size=12, ax=ax)

            # Draw edge labels
            if with_edge_labels:
                nx.draw_networkx_edge_labels(g, pos, edge_labels=edge_labels, ax=ax)
                #label_pos=0.5, font_size=10, font_color='k', font_family='sans-serif', font_weight='normal',
                # alpha=1.0, bbox=None, ax=None, rotate=True, **kwds)

        else:
            raise ValueError("Unknown value for mode: %s" % str(mode))

        ax.axis("off")
        return fig