Factored out a mixin class for IC thresholding.
This commit is contained in:
parent
0523ebab05
commit
3f7215bc35
|
@ -491,7 +491,7 @@ class PlotDagFunction(workflow.Function):
|
|||
ds = dataset.GraphDataset(networkx.adj_matrix(g),
|
||||
[('go-terms', g.nodes()), ('_go-terms', g.nodes())],
|
||||
name="DAG")
|
||||
return [DagPlot(g)]
|
||||
return [ThresholdDagPlot(g)]
|
||||
|
||||
def get_network(self, terms, subtree='bp'):
|
||||
"""Returns a DAG connecting the given terms by including their parents
|
||||
|
@ -558,13 +558,117 @@ class VolcanoPlot(plots.ScatterPlot):
|
|||
name="Volcano plot",
|
||||
sel_dim_2='_p', **kw)
|
||||
|
||||
|
||||
|
||||
class PlotThresholder:
|
||||
"""Mixin class for plots that needs to filter nodes within a threshold
|
||||
range.
|
||||
"""
|
||||
def __init__(self, text="x"):
|
||||
"""Constructor.
|
||||
|
||||
@param text: Name of the variable the threshold is on.
|
||||
"""
|
||||
self._threshold_ds = None
|
||||
self._add_spin_buttons(text)
|
||||
self._sb_min.set_sensitive(False)
|
||||
self._sb_max.set_sensitive(False)
|
||||
|
||||
def set_threshold_dataset(self, ds):
|
||||
"""Sets the dataset to threshold on.
|
||||
|
||||
@param ds: A dataset where one dimension corresponds to the select dimension
|
||||
in the plot, and any other dimensions have length 1
|
||||
"""
|
||||
self._threshold_ds = ds
|
||||
self._sb_min.set_sensitive(True)
|
||||
self._sb_max.set_sensitive(True)
|
||||
|
||||
def _add_spin_buttons(self, text):
|
||||
"""Adds spin buttons to the toolbar for selecting minimum and maximum
|
||||
threshold values on information content."""
|
||||
sb_min = gtk.SpinButton(digits=2)
|
||||
sb_min.set_range(0, 100)
|
||||
sb_min.set_value(0)
|
||||
sb_min.set_increments(.1, 1.)
|
||||
sb_min.connect('value-changed', self._on_value_changed)
|
||||
self._sb_min = sb_min
|
||||
|
||||
sb_max = gtk.SpinButton(digits=2)
|
||||
sb_max.set_range(0, 100)
|
||||
sb_max.set_value(1)
|
||||
sb_max.set_increments(.1, 1.)
|
||||
sb_max.connect('value-changed', self._on_value_changed)
|
||||
self._sb_max = sb_max
|
||||
|
||||
label = gtk.Label(" < %s < " % text)
|
||||
hbox = gtk.HBox()
|
||||
hbox.pack_start(sb_min)
|
||||
hbox.pack_start(label)
|
||||
hbox.pack_start(sb_max)
|
||||
ti = gtk.ToolItem()
|
||||
ti.set_expand(False)
|
||||
ti.add(hbox)
|
||||
sb_min.show()
|
||||
sb_max.show()
|
||||
label.show()
|
||||
hbox.show()
|
||||
ti.show()
|
||||
self._toolbar.insert(ti, -1)
|
||||
ti.set_tooltip(self._toolbar.tooltips, "Set threshold")
|
||||
|
||||
def set_threshold(self, min, max):
|
||||
"""Sets min and max to the given values.
|
||||
Updates the plot accordingly to show only values that have a
|
||||
value within the boundaries. Other values are
|
||||
also excluded from being selected from the plot.
|
||||
@param ic_min Do not show nodes with IC below this value.
|
||||
@param ic_max Do not show nodes with IC above this value.
|
||||
"""
|
||||
ds = self._threshold_ds
|
||||
if ds == None:
|
||||
return
|
||||
|
||||
icnodes = ds.existing_identifiers('go-terms', self.nodes)
|
||||
icindices = ds.get_indices('go-terms', icnodes)
|
||||
a = ravel(ds.asarray()[icindices])
|
||||
good = set(array(icnodes)[(a>=min) & (a<=max)])
|
||||
|
||||
sizes = zeros(len(self.nodes))
|
||||
visible = set()
|
||||
for i, n in enumerate(self.nodes):
|
||||
if n in good:
|
||||
sizes[i] = 50
|
||||
visible.add(n)
|
||||
else:
|
||||
sizes[i] = 0
|
||||
self.visible = visible
|
||||
|
||||
self.node_collection._sizes = sizes
|
||||
self.canvas.draw()
|
||||
|
||||
def get_nodes_within_bounds(self):
|
||||
"""Get a list of all nodes within the bounds of the selection in the
|
||||
seleted dataset.
|
||||
"""
|
||||
pass
|
||||
|
||||
def filter_nodes(self, nodes):
|
||||
"""Filter a list of nodes and return only those that are within the
|
||||
threshold boundaries."""
|
||||
pass
|
||||
|
||||
def _on_value_changed(self, sb):
|
||||
"""Callback on spin button value changes."""
|
||||
min = self._sb_min.get_value()
|
||||
max = self._sb_max.get_value()
|
||||
self.set_threshold(min, max)
|
||||
|
||||
|
||||
class DagPlot(plots.Plot):
|
||||
def __init__(self, graph, dim='go-terms', pos=None, nodecolor='b', nodesize=40,
|
||||
with_labels=False, name='DAG Plot'):
|
||||
|
||||
plots.Plot.__init__(self, name)
|
||||
self._add_ic_spin_buttons()
|
||||
self.nodes = graph.nodes()
|
||||
self.graph = graph
|
||||
self._pos = pos
|
||||
|
@ -630,39 +734,6 @@ class DagPlot(plots.Plot):
|
|||
self.axes.set_frame_on(False)
|
||||
self.fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
|
||||
|
||||
def _add_ic_spin_buttons(self):
|
||||
"""Adds spin buttons to the toolbar for selecting minimum and maximum
|
||||
threshold values on information content."""
|
||||
sb_min = gtk.SpinButton(digits=2)
|
||||
sb_min.set_range(0, 100)
|
||||
sb_min.set_value(0)
|
||||
sb_min.set_increments(.1, 1.)
|
||||
sb_min.connect('value-changed', self._on_ic_value_changed)
|
||||
self._ic_sb_min = sb_min
|
||||
|
||||
sb_max = gtk.SpinButton(digits=2)
|
||||
sb_max.set_range(0, 100)
|
||||
sb_max.set_value(1)
|
||||
sb_max.set_increments(.1, 1.)
|
||||
sb_max.connect('value-changed', self._on_ic_value_changed)
|
||||
self._ic_sb_max = sb_max
|
||||
|
||||
label = gtk.Label(" < IC < ")
|
||||
hbox = gtk.HBox()
|
||||
hbox.pack_start(sb_min)
|
||||
hbox.pack_start(label)
|
||||
hbox.pack_start(sb_max)
|
||||
ti = gtk.ToolItem()
|
||||
ti.set_expand(False)
|
||||
ti.add(hbox)
|
||||
sb_min.show()
|
||||
sb_max.show()
|
||||
label.show()
|
||||
hbox.show()
|
||||
ti.show()
|
||||
self._toolbar.insert(ti, -1)
|
||||
ti.set_tooltip(self._toolbar.tooltips, "Set information content threshold")
|
||||
|
||||
def _calc_pos(self, graph):
|
||||
"""Calculates position for graph nodes using 'dot' layout."""
|
||||
gv_graph = networkx.DiGraph()
|
||||
|
@ -678,44 +749,7 @@ class DagPlot(plots.Plot):
|
|||
pos[k] = v
|
||||
return pos
|
||||
|
||||
def set_ic_threshold(self, ic_min, ic_max):
|
||||
"""Sets Information Content min and max to the given values.
|
||||
Updates the plot accordingly to show only values that have an
|
||||
information content within the boundaries. Other values are
|
||||
also excluded from being selected from the plot.
|
||||
@param ic_min Do not show nodes with IC below this value.
|
||||
@param ic_max Do not show nodes with IC above this value.
|
||||
"""
|
||||
ic = getattr(main.workflow, 'current_ic', None)
|
||||
if ic == None:
|
||||
print "no ic set"
|
||||
return
|
||||
|
||||
icnodes = ic.existing_identifiers('go-terms', self.nodes)
|
||||
icindices = ic.get_indices('go-terms', icnodes)
|
||||
a = ravel(ic.asarray()[icindices])
|
||||
ic_good = set(array(icnodes)[(a>=ic_min) & (a<=ic_max)])
|
||||
|
||||
sizes = zeros(len(self.nodes))
|
||||
visible = set()
|
||||
for i, n in enumerate(self.nodes):
|
||||
if n in ic_good:
|
||||
sizes[i] = 50
|
||||
visible.add(n)
|
||||
else:
|
||||
sizes[i] = 0
|
||||
self.visible = visible
|
||||
|
||||
self.node_collection._sizes = sizes
|
||||
self.canvas.draw()
|
||||
|
||||
def _on_ic_value_changed(self, sb):
|
||||
"""Callback on spin button value changes."""
|
||||
ic_min = self._ic_sb_min.get_value()
|
||||
ic_max = self._ic_sb_max.get_value()
|
||||
self.set_ic_threshold(ic_min, ic_max)
|
||||
|
||||
def rectangle_select_callback(self, x1, y1, x2, y2, key):
|
||||
def points_in_rect(self, x1, y1, x2, y2, key):
|
||||
ydata = self.yaxis_data
|
||||
xdata = self.xaxis_data
|
||||
|
||||
|
@ -732,7 +766,12 @@ class DagPlot(plots.Plot):
|
|||
ids = self.visible.intersection([self.nodes[i] for i in index])
|
||||
else:
|
||||
ids = set([self.nodes[i] for i in index])
|
||||
return ids
|
||||
|
||||
def rectangle_select_callback(self, x1, y1, x2, y2, key):
|
||||
ids = self.points_in_rect(x1, y1, x2, y2, key)
|
||||
ids = self.update_selection(ids, key)
|
||||
|
||||
self.selection_listener(self.current_dim, ids)
|
||||
|
||||
def lasso_select_callback(self, verts, key=None):
|
||||
|
@ -807,9 +846,34 @@ class DagPlot(plots.Plot):
|
|||
self.node_collection.set_array(map_vec)
|
||||
self.node_collection.set_clim(vec_min, vec_max)
|
||||
self.node_collection.update_scalarmappable() #sets facecolors from array
|
||||
self._ic_sb_min.set_range(0, vec_max)
|
||||
self._ic_sb_min.set_value(vec_min)
|
||||
self._ic_sb_max.set_range(0, vec_max)
|
||||
self._ic_sb_max.set_value(vec_max)
|
||||
|
||||
self.canvas.draw()
|
||||
|
||||
|
||||
class ThresholdDagPlot(DagPlot, PlotThresholder):
|
||||
def __init__(self, graph, dim='go-terms', pos=None, nodecolor='b', nodesize=40,
|
||||
with_labels=False, name='DAG Plot'):
|
||||
DagPlot.__init__(self, graph, dim='go-terms', pos=None,
|
||||
nodecolor='b', nodesize=40,
|
||||
with_labels=False, name='DAG Plot')
|
||||
PlotThresholder.__init__(self, "IC")
|
||||
|
||||
def rectangle_select_callback(self, x1, y1, x2, y2, key):
|
||||
ids = self.points_in_rect(x1, y1, x2, y2, key)
|
||||
ids = self.visible.intersection(ids)
|
||||
ids = self.update_selection(ids, key)
|
||||
|
||||
self.selection_listener(self.current_dim, ids)
|
||||
|
||||
def _update_color_from_dataset(self, ds):
|
||||
DagPlot._update_color_from_dataset(self, ds)
|
||||
self.set_threshold_dataset(ds)
|
||||
a = ds.asarray()
|
||||
a_max = max(a[a<inf])
|
||||
a_min = min(a[a>-inf])
|
||||
self._sb_min.set_range(0, a_max)
|
||||
self._sb_min.set_value(a_min)
|
||||
self._sb_max.set_range(0, a_max)
|
||||
self._sb_max.set_value(a_max)
|
||||
|
||||
|
||||
|
|
Reference in New Issue