diff --git a/.travis.yml b/.travis.yml index 37144abc..6b472238 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,6 +19,7 @@ matrix: addons: apt: packages: + - libqt5gui5 # pyqt5>5.11 otherwise cannot load the xcb platform plugin - libflann-dev install: diff --git a/pygsp/plotting.py b/pygsp/plotting.py index eb152c96..56fcc6bf 100644 --- a/pygsp/plotting.py +++ b/pygsp/plotting.py @@ -299,6 +299,8 @@ def _plot_graph(G, vertex_color, vertex_size, highlight, Signal to plot as vertex color (length is the number of vertices). If None, vertex color is set to `graph.plotting['vertex_color']`. Alternatively, a color can be set in any format accepted by matplotlib. + Each vertex color can by specified by an RGB(A) array of dimension + `n_vertices` x 3 (or 4). vertex_size : array-like or int Signal to plot as vertex size (length is the number of vertices). Vertex size ranges from 0.5 to 2 times `graph.plotting['vertex_size']`. @@ -319,6 +321,8 @@ def _plot_graph(G, vertex_color, vertex_size, highlight, ranges from 0.2 to 0.9. If None, edge color is set to `graph.plotting['edge_color']`. Alternatively, a color can be set in any format accepted by matplotlib. + Each edge color can by specified by an RGB(A) array of dimension + `n_edges` x 3 (or 4). Only available with the matplotlib backend. edge_width : array-like or int Signal to plot as edge width (length is the number of edges). @@ -405,20 +409,26 @@ def normalize(x): return np.full(x.shape, 0.5) return 0.75 * (x - x.min()) / ptp + 0.25 - def is_single_color(color): + def is_color(color): + if backend == 'matplotlib': mpl, _, _ = _import_plt() - return mpl.colors.is_color_like(color) - elif backend == 'pyqtgraph': - # No support (yet) for single color with pyqtgraph. - return False + if mpl.colors.is_color_like(color): + return True # single color + try: + return all(map(mpl.colors.is_color_like, color)) # color list + except TypeError: + return False # e.g., color is an int + + else: + return False # No support for pyqtgraph (yet). if vertex_color is None: limits = [0, 0] colorbar = False if backend == 'matplotlib': vertex_color = (G.plotting['vertex_color'],) - elif is_single_color(vertex_color): + elif is_color(vertex_color): limits = [0, 0] colorbar = False else: @@ -438,8 +448,8 @@ def is_single_color(color): if edge_color is None: edge_color = (G.plotting['edge_color'],) - elif not is_single_color(edge_color): - edge_color = np.array(edge_color).squeeze() + elif not is_color(edge_color): + edge_color = np.asarray(edge_color).squeeze() check_shape(edge_color, 'Edge color', G.n_edges) edge_color = 0.9 * normalize(edge_color) edge_color = [ diff --git a/pygsp/tests/test_plotting.py b/pygsp/tests/test_plotting.py index 28f0aa95..0aa29d44 100644 --- a/pygsp/tests/test_plotting.py +++ b/pygsp/tests/test_plotting.py @@ -116,11 +116,14 @@ def test_signals(self): G.plot() def test_color(param, length): for value in ['r', 4*(.5,), length*(2,), np.ones([1, length]), - np.random.RandomState(42).uniform(size=length)]: + np.random.RandomState(42).uniform(size=length), + np.ones([length, 3]), ["red"] * length, + np.random.RandomState(42).rand(length, 4)]: params = {param: value} G.plot(**params) for value in [10, (0.5, 0.5), np.ones([length, 2]), - np.ones([2, length, 3])]: + np.ones([2, length, 3]), + np.ones([length, 3]) * 1.1]: params = {param: value} self.assertRaises(ValueError, G.plot, **params) for value in ['r', 4*(.5)]: