graspologic icon indicating copy to clipboard operation
graspologic copied to clipboard

[BUG] When you have inner and outer hierarchical labels, plotting fails if something in the cartesian product is empty

Open ebridge2 opened this issue 2 years ago • 1 comments

Expected Behavior

The empty communities are omitted entirely.

Actual Behavior

Error.

ValueError: The number of FixedLocator locations (4), usually from a call to set_ticks, does not match the number of ticklabels (6).

Example Code

import numpy as np
import graspologic as gp

n1 = 50; n2 = 50
Baff = [[0.5, 0.2], [0.2, 0.5]]

zvecaff = np.array(["C1" for i in range(0, n1)] + ["C2" for i in range(0, n2)])

# the probability matrix
zvecaff_ohe = np.vstack([[1, 0] for i in range(0, n1)] + [[0, 1] for i in range(0, n2)])
Paff = zvecaff_ohe @ Baff @ zvecaff_ohe.T

np1 = 15; nc = 70; np2 = 15
Bcp = [[0.2, 0.2, 0.05],
      [0.2, 0.5, 0.2],
      [0.05, 0.2, 0.2]]


zveccp = np.array(["P1" for i in range(0, np1)] +
                  ["Core" for i in range(0, nc)] +
                  ["P2" for i in range(0, np2)])

# the probability matrix
zveccp_ohe = np.vstack([[1, 0, 0] for i in range(0, np1)] + 
                       [[0, 1, 0] for i in range(0, nc)] +
                       [[0, 0, 1] for i in range(0, np2)])
Pcp = zveccp_ohe @ Bcp @ zveccp_ohe.T

Pcp_and_aff = (Paff + Pcp)/2
Acp_and_aff = gp.simulations.sample_edges(Pcp_and_aff, directed=False, loops=False)


gp.plot.heatmap(Pcp, inner_hier_labels=zveccp, outer_hier_labels=zvecaff,
                title="Core-periphery and affinity prob. P^{(cp + a)}$", vmin=0, vmax=1, cmap=cmaps["sequential"]);

Full Traceback

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-63-9fa6c510a0a5> in <module>
      1 fig, axs = plt.subplots(1,2, figsize=(10,4))
      2 
----> 3 gp.plot.heatmap(Pcp, ax=axs[0], inner_hier_labels=zveccp, outer_hier_labels=zvecaff,
      4                 title="Core-periphery and affinity prob. P^{(cp + a)}$", vmin=0, vmax=1, cmap=cmaps["sequential"]);
      5 gp.plot.heatmap(Acp, ax=axs[1], inner_hier_labels=zveccp, outer_hier_labels=zvecaff,

~/.virtualenvs/graph-book/lib/python3.8/site-packages/graspologic/plot/plot.py in heatmap(X, transform, figsize, title, context, font_scale, xticklabels, yticklabels, cmap, vmin, vmax, center, cbar, inner_hier_labels, outer_hier_labels, hier_label_fontsize, ax, title_pad, sort_nodes, **kwargs)
    353                 plot.set_yticklabels([])
    354                 plot.set_xticklabels([])
--> 355                 _plot_groups(
    356                     plot,
    357                     arr,

~/.virtualenvs/graph-book/lib/python3.8/site-packages/graspologic/plot/plot.py in _plot_groups(ax, graph, inner_labels, outer_labels, fontsize)
   1611     ax_x = divider.new_vertical(size="5%", pad=0.0, pack_start=False)
   1612     ax.figure.add_axes(ax_x)
-> 1613     _plot_brackets(
   1614         ax_x,
   1615         np.tile(inner_unique, len(outer_unique)),

~/.virtualenvs/graph-book/lib/python3.8/site-packages/graspologic/plot/plot.py in _plot_brackets(ax, group_names, tick_loc, tick_width, curve, level, axis, max_size, fontsize)
   1696     if axis == "x":
   1697         ax.set_xticks(tick_loc)
-> 1698         ax.set_xticklabels(group_names, fontsize=fontsize, verticalalignment="center")
   1699         ax.xaxis.set_label_position("top")
   1700         ax.xaxis.tick_top()

~/.virtualenvs/graph-book/lib/python3.8/site-packages/matplotlib/axes/_base.py in wrapper(self, *args, **kwargs)
     73 
     74         def wrapper(self, *args, **kwargs):
---> 75             return get_method(self)(*args, **kwargs)
     76 
     77         wrapper.__module__ = owner.__module__

~/.virtualenvs/graph-book/lib/python3.8/site-packages/matplotlib/axis.py in _set_ticklabels(self, labels, fontdict, minor, **kwargs)
   1796         if fontdict is not None:
   1797             kwargs.update(fontdict)
-> 1798         return self.set_ticklabels(labels, minor=minor, **kwargs)
   1799 
   1800     def _set_tick_locations(self, ticks, *, minor=False):

~/.virtualenvs/graph-book/lib/python3.8/site-packages/matplotlib/axis.py in set_ticklabels(self, ticklabels, minor, **kwargs)
   1718             # remove all tick labels, so only error for > 0 ticklabels
   1719             if len(locator.locs) != len(ticklabels) and len(ticklabels) != 0:
-> 1720                 raise ValueError(
   1721                     "The number of FixedLocator locations"
   1722                     f" ({len(locator.locs)}), usually from a call to"

ValueError: The number of FixedLocator locations (4), usually from a call to set_ticks, does not match the number of ticklabels (6).

Your Environment

  • Python version: 3.8
  • graspologic version: 1.0.1

Additional Details

Any other contextual information you might feel is important.

ebridge2 avatar Mar 15 '22 13:03 ebridge2

In the example, the cartesian product of the inner/outer hierarchies has 6 elements, but the actual network only has 4, since one of the inner communities are not possible in each of the two outer communities, yielding only 4 realized communities in the network.

ebridge2 avatar Mar 15 '22 13:03 ebridge2