Factored out a mixin class for IC thresholding.

This commit is contained in:
Einar Ryeng 2007-08-03 12:09:17 +00:00
parent 0523ebab05
commit 3f7215bc35

View File

@ -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)