Exemplo n.º 1
0
    def depExportGraph(self, f, n_int=1, print_bits = 1, black_white = 0, undirected = 1, significant_digits = 2, pretty_names = 1, pcutoff=-1, postscript=1, spanning_tree = 1, TAN=1, source=-1, labelled=1,jaccard=1,filter=[],diagonal=0,pvlabel=0):
        NA = self.NA

        ### SELECTION OF INTERACTIONS AND ATTRIBUTES ###

        links = []
        maxlink = -1e6
        if n_int == 1 and spanning_tree:
            # prepare table
            lmm = []
            for i in range(1,NA):
                ei = self.ents[(i,)]
                for j in range(i):
                    ej = self.ents[(j,)]
                    if TAN:
                        # I(A;B|C)
                        v = self.way3[(j,i,-1)].InteractionInformation()
                        v += self.way2[(j,i)].InteractionInformation()
                    else:
                        if jaccard:
                            v = self.way2[(j,i)].JaccardInteraction() # I(A;B) chow-liu, mutual information
                        else:
                            v = self.way2[(j,i)].InteractionInformation() # I(A;B) chow-liu, mutual information
                    if ei > ej:
                        lmm.append((abs(v),v,ej,(j,i)))
                    else:
                        lmm.append((abs(v),v,ei,(i,j)))
            lmm.sort()
            maxlink = lmm[-1][0]
            # use Prim's algorithm here
            mapped = []
            for i in range(NA):
                mapped.append(i)
            n = NA
            idx = -1 # running index in the sorted array of possible links
            while n > 1:
                # find the cheapest link
                while 1:
                    (av,v,e,(i,j)) = lmm[idx]
                    idx -= 1
                    if mapped[i] != mapped[j]:
                        break
                links.append((v,(i,j),e))
                toremove = mapped[j]
                for k in range(NA):
                    if mapped[k] == toremove:
                        mapped[k] = mapped[i]
                n -= 1
        else:
            # select the top
            lmm = []
            for i in range(NA):
                if filter==[] or self.names[i] in filter:
                    for j in range(i):
                        if filter==[] or self.names[j] in filter:
                            ii = max(i,j)
                            jj = min(i,j)
                            if jaccard and pcutoff < 0.0:
                                if self.ents[(jj,ii)] == 0.0:
                                    v = 1.0
                                else:
                                    v = self.way2[(jj,ii)].JaccardInteraction()
                                lmm.append((v,(i,j)))
                            else:
                                v = self.way2[(jj,ii)].InteractionInformation()
                                if pcutoff >= 0.0:
                                    xt = self.way2[(jj,ii)]
                                    dof = 1.0
                                    dof *= len(xt.values[0])-1
                                    dof *= len(xt.values[1])-1
                                    pv = orngContingency.getPvalueDOF(v,xt,dof)
                                    if pv <= pcutoff:
                                        v = 1-pv
                                        lmm.append((v,(i,j)))
                                else:
                                    lmm.append((v,(i,j)))
            lmm.sort()
            maxlink = max(lmm[-1][0],maxlink)
            links += [(v,p,1.0) for (v,p) in lmm[-n_int:]]

        # mark vertices
        mv = [0 for x in range(NA)]
        for (v,(i,j),e) in links:
            mv[i] = 1
            mv[j] = 1

        # output the attributes
        f.write("digraph G {\n")

        if print_bits:
            shap = 'record'
        else:
            shap = 'box'

        for n in range(NA):
            if mv[n]:
                if source != -1 and not type(source)==type(1):
                    # find the name
                    if string.upper(self.names[n])==string.upper(source):
                        source = n
                t = '%s'%self.names[n]
                if pretty_names:
                    t = string.replace(t,"ED_","")
                    t = string.replace(t,"D_","")
                    t = string.replace(t,"M_","")
                    t = string.replace(t," ","\\n")
                    t = string.replace(t,"-","\\n")
                    t = string.replace(t,"_","\\n")
                if print_bits:
                    #t = "{%s|%s}"%(t,_nicefloat(self.ents[(n,)],significant_digits))
                    t = "{%s|%s}"%(t,_nicefloat(self.way2[(n,-1)].total,significant_digits))
                f.write("\tnode [ shape=%s, label = \"%s\"] %d;\n"%(shap,t,n))

        if source != -1:
            # redirect all links
            age = [-1]*NA
            age[source] = 0
            phase = 1
            remn = NA-1
            premn = -1
            while remn > 0 and premn != remn:
                premn = remn
                for (v,(i,j),e) in links:
                    if age[i] >= 0 and age[i] < phase and age[j] < 0:
                        age[j] = phase
                        remn -= 1
                    if age[j] >= 0 and age[j] < phase and age[i] < 0:
                        age[i] = phase
                        remn -= 1
                phase += 1

        ### EDGE DRAWING ###
        for (v,(i,j),e) in links:
            if v > 0:
                c = v/e
                perc = int(100*v/maxlink + 0.5)

                style = ''
                if postscript:
                    style += "style=\"setlinewidth(%d)\","%(abs(perc)/30+1)
                if not black_white:
                    l = 0.3+0.7*perc/100.0
                    style += 'color="0.5 %f %f",'%(l,1-l) # adjust saturation
                if labelled:
                    if diagonal:
                        ct = self.way2[(min(i,j),max(i,j))]
                        (ni,nj) = numpy.shape(ct.m)
                        cc = 0.0
                        if ni==nj:
                            for x in range(ni):
                                cc += ct.m[x,x]
                        style += 'label=\"%s%%\",'%_nicefloat(100.0*cc/ct.total,significant_digits)
                    elif pvlabel and pcutoff >= 0.0:
                        style += 'label=\"%e\",'%(1-v)
                    else:
                        style += 'label=\"%s%%\",'%_nicefloat(100.0*c,significant_digits)
                if source == -1 or undirected:
                    f.write("\t%d -> %d [%sweight=%d,dir=none];\n"%(j,i,style,(perc/30+1)))
                else:
                    if age[i] > age[j]:
                        f.write("\t%d -> %d [%sweight=%d];\n"%(j,i,style,(perc/30+1)))
                    else:
                        f.write("\t%d -> %d [%sweight=%d];\n"%(i,j,style,(perc/30+1)))
        f.write("}\n")
Exemplo n.º 2
0
    def depExportGraph(self,
                       f,
                       n_int=1,
                       print_bits=1,
                       black_white=0,
                       undirected=1,
                       significant_digits=2,
                       pretty_names=1,
                       pcutoff=-1,
                       postscript=1,
                       spanning_tree=1,
                       TAN=1,
                       source=-1,
                       labelled=1,
                       jaccard=1,
                       filter=[],
                       diagonal=0,
                       pvlabel=0):
        NA = self.NA

        ### SELECTION OF INTERACTIONS AND ATTRIBUTES ###

        links = []
        maxlink = -1e6
        if n_int == 1 and spanning_tree:
            # prepare table
            lmm = []
            for i in range(1, NA):
                ei = self.ents[(i, )]
                for j in range(i):
                    ej = self.ents[(j, )]
                    if TAN:
                        # I(A;B|C)
                        v = self.way3[(j, i, -1)].InteractionInformation()
                        v += self.way2[(j, i)].InteractionInformation()
                    else:
                        if jaccard:
                            v = self.way2[(j, i)].JaccardInteraction(
                            )  # I(A;B) chow-liu, mutual information
                        else:
                            v = self.way2[(j, i)].InteractionInformation(
                            )  # I(A;B) chow-liu, mutual information
                    if ei > ej:
                        lmm.append((abs(v), v, ej, (j, i)))
                    else:
                        lmm.append((abs(v), v, ei, (i, j)))
            lmm.sort()
            maxlink = lmm[-1][0]
            # use Prim's algorithm here
            mapped = []
            for i in range(NA):
                mapped.append(i)
            n = NA
            idx = -1  # running index in the sorted array of possible links
            while n > 1:
                # find the cheapest link
                while 1:
                    (av, v, e, (i, j)) = lmm[idx]
                    idx -= 1
                    if mapped[i] != mapped[j]:
                        break
                links.append((v, (i, j), e))
                toremove = mapped[j]
                for k in range(NA):
                    if mapped[k] == toremove:
                        mapped[k] = mapped[i]
                n -= 1
        else:
            # select the top
            lmm = []
            for i in range(NA):
                if filter == [] or self.names[i] in filter:
                    for j in range(i):
                        if filter == [] or self.names[j] in filter:
                            ii = max(i, j)
                            jj = min(i, j)
                            if jaccard and pcutoff < 0.0:
                                if self.ents[(jj, ii)] == 0.0:
                                    v = 1.0
                                else:
                                    v = self.way2[(jj,
                                                   ii)].JaccardInteraction()
                                lmm.append((v, (i, j)))
                            else:
                                v = self.way2[(jj,
                                               ii)].InteractionInformation()
                                if pcutoff >= 0.0:
                                    xt = self.way2[(jj, ii)]
                                    dof = 1.0
                                    dof *= len(xt.values[0]) - 1
                                    dof *= len(xt.values[1]) - 1
                                    pv = orngContingency.getPvalueDOF(
                                        v, xt, dof)
                                    if pv <= pcutoff:
                                        v = 1 - pv
                                        lmm.append((v, (i, j)))
                                else:
                                    lmm.append((v, (i, j)))
            lmm.sort()
            maxlink = max(lmm[-1][0], maxlink)
            links += [(v, p, 1.0) for (v, p) in lmm[-n_int:]]

        # mark vertices
        mv = [0 for x in range(NA)]
        for (v, (i, j), e) in links:
            mv[i] = 1
            mv[j] = 1

        # output the attributes
        f.write("digraph G {\n")

        if print_bits:
            shap = 'record'
        else:
            shap = 'box'

        for n in range(NA):
            if mv[n]:
                if source != -1 and not type(source) == type(1):
                    # find the name
                    if string.upper(self.names[n]) == string.upper(source):
                        source = n
                t = '%s' % self.names[n]
                if pretty_names:
                    t = string.replace(t, "ED_", "")
                    t = string.replace(t, "D_", "")
                    t = string.replace(t, "M_", "")
                    t = string.replace(t, " ", "\\n")
                    t = string.replace(t, "-", "\\n")
                    t = string.replace(t, "_", "\\n")
                if print_bits:
                    #t = "{%s|%s}"%(t,_nicefloat(self.ents[(n,)],significant_digits))
                    t = "{%s|%s}" % (t,
                                     _nicefloat(self.way2[(n, -1)].total,
                                                significant_digits))
                f.write("\tnode [ shape=%s, label = \"%s\"] %d;\n" %
                        (shap, t, n))

        if source != -1:
            # redirect all links
            age = [-1] * NA
            age[source] = 0
            phase = 1
            remn = NA - 1
            premn = -1
            while remn > 0 and premn != remn:
                premn = remn
                for (v, (i, j), e) in links:
                    if age[i] >= 0 and age[i] < phase and age[j] < 0:
                        age[j] = phase
                        remn -= 1
                    if age[j] >= 0 and age[j] < phase and age[i] < 0:
                        age[i] = phase
                        remn -= 1
                phase += 1

        ### EDGE DRAWING ###
        for (v, (i, j), e) in links:
            if v > 0:
                c = v / e
                perc = int(100 * v / maxlink + 0.5)

                style = ''
                if postscript:
                    style += "style=\"setlinewidth(%d)\"," % (abs(perc) / 30 +
                                                              1)
                if not black_white:
                    l = 0.3 + 0.7 * perc / 100.0
                    style += 'color="0.5 %f %f",' % (l, 1 - l
                                                     )  # adjust saturation
                if labelled:
                    if diagonal:
                        ct = self.way2[(min(i, j), max(i, j))]
                        (ni, nj) = numpy.shape(ct.m)
                        cc = 0.0
                        if ni == nj:
                            for x in range(ni):
                                cc += ct.m[x, x]
                        style += 'label=\"%s%%\",' % _nicefloat(
                            100.0 * cc / ct.total, significant_digits)
                    elif pvlabel and pcutoff >= 0.0:
                        style += 'label=\"%e\",' % (1 - v)
                    else:
                        style += 'label=\"%s%%\",' % _nicefloat(
                            100.0 * c, significant_digits)
                if source == -1 or undirected:
                    f.write("\t%d -> %d [%sweight=%d,dir=none];\n" %
                            (j, i, style, (perc / 30 + 1)))
                else:
                    if age[i] > age[j]:
                        f.write("\t%d -> %d [%sweight=%d];\n" %
                                (j, i, style, (perc / 30 + 1)))
                    else:
                        f.write("\t%d -> %d [%sweight=%d];\n" %
                                (i, j, style, (perc / 30 + 1)))
        f.write("}\n")