Skip to content

Commit

Permalink
Implemented and documented Graph edge_color_index
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Nov 23, 2017
1 parent 184cf82 commit a7eeaf8
Show file tree
Hide file tree
Showing 10 changed files with 295 additions and 103 deletions.
10 changes: 6 additions & 4 deletions examples/reference/elements/bokeh/Graph.ipynb
Expand Up @@ -90,7 +90,7 @@
"source": [
"#### Additional features\n",
"\n",
"Next we will extend this example by supplying explicit edges:"
"Next we will extend this example by supplying explicit edges, node information and edge weights. By constructing the ``Nodes`` explicitly we can declare an additional value dimensions, which are revealed when hovering and/or can be mapped to the color by specifying the ``color_index``. We can also associate additional information with each edge by supplying a value dimension to the ``Graph`` itself, which we can map to a color using the ``edge_color_index``."
]
},
{
Expand All @@ -100,8 +100,10 @@
"outputs": [],
"source": [
"# Node info\n",
"np.random.seed(7)\n",
"x, y = simple_graph.nodes.array([0, 1]).T\n",
"node_labels = ['Output']+['Input']*(N-1)\n",
"edge_weights = np.random.rand(8)\n",
"\n",
"# Compute edge paths\n",
"def bezier(start, end, control, steps=np.linspace(0, 1, 100)):\n",
Expand All @@ -114,10 +116,10 @@
"\n",
"# Declare Graph\n",
"nodes = hv.Nodes((x, y, node_indices, node_labels), vdims='Type')\n",
"graph = hv.Graph(((source, target), nodes, paths))\n",
"graph = hv.Graph(((source, target, edge_weights), nodes, paths), vdims='Weight')\n",
"\n",
"graph.redim.range(**padding).opts(plot=dict(color_index='Type'),\n",
" style=dict(cmap=['blue', 'yellow']))"
"graph.redim.range(**padding).opts(plot=dict(color_index='Type', edge_color_index='Weight'),\n",
" style=dict(cmap=['blue', 'red'], edge_cmap='viridis'))"
]
}
],
Expand Down
13 changes: 7 additions & 6 deletions examples/reference/elements/matplotlib/Graph.ipynb
Expand Up @@ -90,7 +90,8 @@
"source": [
"#### Additional features\n",
"\n",
"Next we will extend this example by supplying explicit edges:"
"\n",
"Next we will extend this example by supplying explicit edges, node information and edge weights. By constructing the ``Nodes`` explicitly we can declare an additional value dimensions, which are revealed when hovering and/or can be mapped to the color by specifying the ``color_index``. We can also associate additional information with each edge by supplying a value dimension to the ``Graph`` itself, which we can map to a color using the ``edge_color_index``."
]
},
{
Expand All @@ -99,11 +100,11 @@
"metadata": {},
"outputs": [],
"source": [
"from matplotlib.colors import ListedColormap\n",
"\n",
"# Node info\n",
"np.random.seed(7)\n",
"x, y = simple_graph.nodes.array([0, 1]).T\n",
"node_labels = ['Output']+['Input']*(N-1)\n",
"edge_weights = np.random.rand(8)\n",
"\n",
"# Compute edge paths\n",
"def bezier(start, end, control, steps=np.linspace(0, 1, 100)):\n",
Expand All @@ -116,10 +117,10 @@
"\n",
"# Declare Graph\n",
"nodes = hv.Nodes((x, y, node_indices, node_labels), vdims='Type')\n",
"graph = hv.Graph(((source, target), nodes, paths))\n",
"graph = hv.Graph(((source, target, edge_weights), nodes, paths), vdims='Weight')\n",
"\n",
"graph.redim.range(**padding).opts(plot=dict(color_index='Type'),\n",
" style=dict(cmap=ListedColormap(['blue', 'yellow'])))"
"graph.redim.range(**padding).opts(plot=dict(color_index='Type', edge_color_index='Weight'),\n",
" style=dict(cmap=['blue', 'red'], edge_cmap='viridis'))"
]
}
],
Expand Down
13 changes: 7 additions & 6 deletions examples/user_guide/Network_Graphs.ipynb
Expand Up @@ -43,8 +43,8 @@
"source": [
"# Declare abstract edges\n",
"N = 8\n",
"node_indices = np.arange(N)\n",
"source = np.zeros(N)\n",
"node_indices = np.arange(N, dtype=np.int32)\n",
"source = np.zeros(N, dtype=np.int32)\n",
"target = node_indices\n",
"\n",
"padding = dict(x=(-1.2, 1.2), y=(-1.2, 1.2))\n",
Expand Down Expand Up @@ -148,7 +148,7 @@
"source": [
"#### Additional information\n",
"\n",
"We can also associate additional information with the nodes and edges of a graph. By constructing the ``Nodes`` explicitly we can declare an additional value dimensions, which are revealed when hovering and/or can be mapped to the color by specifying the ``color_index``. We can also associate additional information with each edge by supplying a value dimension to the ``Graph`` itself."
"We can also associate additional information with the nodes and edges of a graph. By constructing the ``Nodes`` explicitly we can declare an additional value dimensions, which are revealed when hovering and/or can be mapped to the color by specifying the ``color_index``. We can also associate additional information with each edge by supplying a value dimension to the ``Graph`` itself, which we can map to a color using the ``edge_color_index``."
]
},
{
Expand All @@ -157,12 +157,13 @@
"metadata": {},
"outputs": [],
"source": [
"%%opts Graph [color_index='Type'] (cmap='Set1')\n",
"%%opts Graph [color_index='Type' edge_color_index='Weight'] (cmap='Set1' edge_cmap='viridis')\n",
"node_labels = ['Output']+['Input']*(N-1)\n",
"edge_labels = list('ABCDEFGH')\n",
"np.random.seed(7)\n",
"edge_labels = np.random.rand(8)\n",
"\n",
"nodes = hv.Nodes((x, y, node_indices, node_labels), vdims='Type')\n",
"graph = hv.Graph(((source, target, edge_labels), nodes, paths), vdims='Label').redim.range(**padding)\n",
"graph = hv.Graph(((source, target, edge_labels), nodes, paths), vdims='Weight').redim.range(**padding)\n",
"graph + graph.opts(plot=dict(inspection_policy='edges'))"
]
},
Expand Down
9 changes: 9 additions & 0 deletions holoviews/core/util.py
Expand Up @@ -1569,3 +1569,12 @@ def dt_to_int(value, time_unit='us'):
except:
# Handle python2
return (time.mktime(value.timetuple()) + value.microsecond / 1e6) * tscale


def search_indices(values, source):
"""
Given a set of values returns the indices of each of those values
in the source array.
"""
orig_indices = source.argsort()
return orig_indices[np.searchsorted(source[orig_indices], values)]
11 changes: 5 additions & 6 deletions holoviews/plotting/bokeh/element.py
Expand Up @@ -5,7 +5,6 @@
import numpy as np
import bokeh
import bokeh.plotting
from bokeh import palettes
from bokeh.core.properties import value
from bokeh.models import (HoverTool, Renderer, Range1d, DataRange1d, Title,
FactorRange, FuncTickFormatter, Tool, Legend)
Expand All @@ -20,7 +19,7 @@
from bokeh.plotting.helpers import _known_tools as known_tools

from ...core import DynamicMap, CompositeOverlay, Element, Dimension
from ...core.options import abbreviated_exception, SkipRendering, Cycle
from ...core.options import abbreviated_exception, SkipRendering
from ...core import util
from ...streams import Stream, Buffer
from ..plot import GenericElementPlot, GenericOverlayPlot
Expand Down Expand Up @@ -1102,7 +1101,7 @@ def _draw_colorbar(self, plot, color_mapper):


def _get_colormapper(self, dim, element, ranges, style, factors=None, colors=None,
cycle=None, name='color_mapper'):
name='color_mapper'):
# The initial colormapper instance is cached the first time
# and then only updated
if dim is None and colors is None:
Expand All @@ -1124,7 +1123,7 @@ def _get_colormapper(self, dim, element, ranges, style, factors=None, colors=Non
else:
low, high = None, None

cmap = colors or cycle or style.pop('cmap', 'viridis')
cmap = colors or style.pop('cmap', 'viridis')
palette = process_cmap(cmap, ncolors)
nan_colors = {k: rgba_tuple(v) for k, v in self.clipping_colors.items()}
colormapper, opts = self._get_cmapper_opts(low, high, factors, nan_colors)
Expand All @@ -1145,7 +1144,7 @@ def _get_colormapper(self, dim, element, ranges, style, factors=None, colors=Non


def _get_color_data(self, element, ranges, style, name='color', factors=None, colors=None,
cycle=None, int_categories=False):
int_categories=False):
data, mapping = {}, {}
cdim = element.get_dimension(self.color_index)
if not cdim:
Expand All @@ -1162,7 +1161,7 @@ def _get_color_data(self, element, ranges, style, name='color', factors=None, co
factors = [str(f) for f in factors]

mapper = self._get_colormapper(cdim, element, ranges, style,
factors, colors, cycle)
factors, colors)
data[field] = cdata
if factors is not None:
mapping['legend'] = {'field': field}
Expand Down

0 comments on commit a7eeaf8

Please sign in to comment.