Hi Tiago,
sometimes, when delete the graph and create a new one, then plot it, the
plotted graph is shown upside down (in terms of the node text). So how could
we control the orientation of the graph? Or which parameter we should use to
always make node text shown in a correct orientation. Thanks a lot.
--
View this message in context: http://main-discussion-list-for-the-graph-tool-project.982480.n3.nabble.com…
Sent from the Main discussion list for the graph-tool project mailing list archive at Nabble.com.

Hi,
I'm suffering from the same issue mentioned in this post:
https://git.skewed.de/count0/graph-tool/issues/174
Namely, I'm trying to draw a graph that includes a lot of self-looping
edges, and my labels are being printed upside down. If I remove the
self-loops the labels are shown the right way up.
Is there a fix for it?
Thanks,
Charlie
--
View this message in context: http://main-discussion-list-for-the-graph-tool-project.982480.n3.nabble.com…
Sent from the Main discussion list for the graph-tool project mailing list archive at Nabble.com.

Hello,
I'm studying political coalitions over time (three time slices) and across discrete types of relationships (collaboration, ideological similarity, and discursive similarity). Since graph-tool offers (the only) principled approach that does not require arbitrary user-specified parameters (such as 'resolution' or 'coupling'), I would very much like to use it for my analysis.
I'm trying to fit a SBM to a graph with edges divided into distinct layers (three time slices X three types of relationships). Each edge has a discrete weight in the range of [0, 3], with weight referring to the 'strength' of the relationship. Not all nodes participate in all layers.
I'm interested in how/if the block membership varies across layers that I expect to be somewhat dependent on one another (hence I would like to avoid fitting a separate SBM to each layer). In my ideal scenario, I would be using the NestedBlockState with LayeredBlockState as base and allowing for overlaps across layers:
state=NestedBlockState(g, base_type=LayeredBlockState, state_args=dict(deg_corr=True, overlap=True, layers=True, ec=g.ep.layer, recs=[g.ep.weight], rec_types=["discrete-binomial"]))
dS, nmoves=0, 0
for i in range(100):
ret=state.multiflip_mcmc_sweep(niter=10)
dS+=ret[0]
nmoves+=ret[1]
print("Change in description length:", dS)
print("Number of accepted vertex moves:", nmoves)
mcmc_equilibrate(state, wait=1000, mcmc_args=dict(niter=10), verbose=True)
bs=[]
def collect_partitions(s):
global bs
bs.append(s.get_bs())
mcmc_equilibrate(state, force_niter=10000, mcmc_args=dict(niter=10), verbose=True, callback=collect_partitions)
pm=PartitionModeState(bs, nested=True, converge=True)
pv=pm.get_marginal(g)
bs=pm.get_max_nested()
state=state.copy(bs=bs)
Two questions:
Q1)
This is taking very long (days) on a high performance cluster and actually I haven't seen it finishing up for once. Is my model specification correct or simply too complex? If the latter, is there a better strategy to perform my analysis? All I can think of is to revert to a non-nested model and/or reduce the number of layers and/or edges:
state=LayeredBlockState(g, deg_corr=True, overlap=True, layers=True, ec=g.ep.layer, recs=[g.ep.weight], rec_types=["discrete-binomial"])
dS, nattempts, nmoves=state.multiflip_mcmc_sweep(niter=1000)
print("Change in description length:", dS)
print("Number of accepted vertex moves:", nmoves)
mcmc_equilibrate(state, wait=1000, nbreaks=2, mcmc_args=dict(niter=10), verbose=True)
bs=[]
def collect_partitions(s):
global bs
bs.append(s.b.a.copy())
mcmc_equilibrate(state, force_niter=10000, mcmc_args=dict(niter=10), verbose=True, callback=collect_partitions)
pm=PartitionModeState(bs, converge=True)
pv=pm.get_marginal(g)
Q2)
Say that the model runs and yields a neat NestedBlockState (or LayeredBlockState) object with X overlapping blocks, 9 layers, degree-corrected, with 2 edge covariates, for graph <Graph object, undirected, with 220 vertices and 11322 edges, 2 internal vertex properties, 4 internal edge properties>.
Now, in previous posts there are mentions about the number of nodes multiplying by the number of layers when 'overlap=True', but in my experiments with only two layers, this does not seem to be the case and I struggle to find a way to extract the layer-specific block and respective memberships of nodes.
I've tried iteration over vertices, but what I eventually need is a 2d_array [y=all nodes in g, x=all layers in g, values=most likely block membership] in order to map how/if the block membership of each node varies across those layers in which they participate (ideally somehow denoting non-participation in the layer with NaN or some unique value). Is there some way to get there?
l=state.get_levels()[0] #NestedBlockState
B=l.get_nonempty_B()
bv=l.get_overlap_blocks()[0]
z=np.zeros((g.num_vertices(), B)) #to be filled with most likely block membership with potential overlaps across ALL layers, but I need the layer-specific information
for i in range(g.num_vertices()):
z[int(i), :len(z[v])]=bv[i].a+1
for v in range(g.num_vertices()*max(g.ep.layer)+1): #to see if the number of vertices multiplied by layers, which it didn't
print(bv[v])
Many thanks,
Arttu

hi,
installing on linux using conda-forge gives the following error
anaconda3/envs/gt/bin/gtk-query-immodules-3.0: error while loading shared libraries: libXcursor.so.1: cannot open shared object file: No such file or directory
ERROR: Failed to complete gtk3's post-link script.
To fix this, activate the environment and run:
glib-compile-schemas "/home/anaconda3/envs/gt/share/glib-2.0/schemas"
gtk-update-icon-cache -f -t "/home/anaconda3/envs/gt/share/icons/hicolor"
gtk-query-immodules-3.0 --update-cache
unfortunately running the three suggested lines gives another error
gtk-query-immodules-3.0: error while loading shared libraries: libXcursor.so.1: cannot open shared object file: No such file or directory
and running graph-tool also gives an error
any ideas?

Hi,
I got a strange problem. I have this code (simplified, the Graph represented by graph_tool is a control flow graph):
```
class CFG(graph_tool.Graph):
def get_function_bbs(self, function):
print(self.vertex(function))
for edge in self.vertex(function).out_edges():
print(edge.__dict__)
print(edge)
if self.ep.type[edge] == CFType.f2b:
yield edge.target()
```
Calling the function `get_function_bbs` now leads to a `ValueError: invalid edge descriptor`. The stack trace says the `print(edge)` instruction is responsible for the error:
```
File "/.../graph.py", line 93, in get_function_bbs
print(edge)
ValueError: invalid edge descriptor
```
In my tests the function is called many times. This is the output (--- indicates a new call of get_function_bbs)
```
---
12
{}
(12, 13)
---
24
{}
(24, 25)
---
40
{}
(40, 41)
---
71
{}
(71, 72)
{}
(71, 73)
{}
```
So: `71` is the vertex, where the functions fails. There are two edges `(71, 72)` and `(71, 73)` where the descriptor is valid and another unknown edge that is _not_ valid.
All edge descriptors have no dict.
My question: How can I debug this and find out, why it is invalid? Can I do/print anything in Python? Should I use GDB? Where would be a good place to set a breakpoint?
I cannot print the faulty edge. It is fairly complicate to make an minimal example. My whole code uses no remove_edge() or remove_vertex(). I'm using graph_tool 2.43.
Best,
Gerion

Hi, list. Lets call a topological sort of a graph stable, if it preserves
some total ordering of nodes, if the topological order for these nodes is
not defined. The StackOverflow question [1] captures the problem, and the
pshufb's answer seems correct to me.
How would you implement such a sort using graph_tool, which AFAIK has only
an "unstable" version? Would it be possible to run 'topological_sort' on a
copied graph with additional edges in it?
BR,
Sergey
[1] https://stackoverflow.com/questions/11230881/stable-topological-sort

Hi all, I have a NestedBlockState with LayeredBlockState as basis, two layers. I would like to predict edges that are missing in one or the other layer (besides, is this even possible?). However, given a list of missing edges (and a list of spurious ones) I tried this
a_state.get_edges_prob(missing, spurious)
and get this error
AttributeError Traceback (most recent call last)
<ipython-input-68-b3bc5280d3da> in <module>
----> 1 a_state.get_edges_prob([missing], spurious)
~/anaconda3/envs/experimental/lib/python3.8/site-packages/graph_tool/inference/nested_blockmodel.py in get_edges_prob(self, missing, spurious, entropy_args)
441 lstate._state.clear_egroups()
442
--> 443 L += lstate.get_edges_prob(missing, spurious, entropy_args=eargs)
444 if isinstance(self.levels[0], LayeredBlockState):
445 missing = [(lstate.b[u], lstate.b[v], l_) for u, v, l_ in missing]
~/anaconda3/envs/experimental/lib/python3.8/site-packages/graph_tool/inference/blockmodel.py in get_edges_prob(self, missing, spurious, entropy_args)
1204 pos[v] = self.b[v]
1205
-> 1206 self.remove_vertex(pos.keys())
1207
1208 try:
~/anaconda3/envs/experimental/lib/python3.8/site-packages/graph_tool/inference/blockmodel.py in remove_vertex(self, v)
1144 twice.
1145 """
-> 1146 self._state.remove_vertex(int(v))
1147
1148 def add_vertex(self, v, r):
AttributeError: 'graph_tool::BlockState<boost::undirected_adaptor<b' object has no attribute 'remove_vertex'
I'm not sure what's happening here, but as far as I know gt.BlockState (and gt.NestedBlockState and gt.LayeredBlockState) have a remove_vertex method defined, right?

Dear Tiago,
I have a directed graph of about half a million nodes and approximately a
million edges following scale free behaviour and a power law degree
distribution. To test some of my hypothesis, I would like to generate random
smaller graphs (about 50 up to 200 nodes) representative of the big one.
When I used a sample function that samples straight away from the real
distribution of the big network, I have following problems:
- I generate unconnected nodes with both 0 in AND out degree.
- I generate small sub parts of a few nodes that are not connected to the
main graph.
- If only sampling from nodes with at least 1 degree, the generated graph is
coherent, but not representative anymore as I need a big portion of nodes
with either only one in or one out degree.
Here is the part of my script I used for that, where samples are drawn from
dictionaries of the degrees:
def sample_in():
a=np.random.randint(num)
k_in = in_degrees[a]
return k_in
def sample_out():
if sample_in()==0:
b=np.random.randint(num_out)
k_out=out_zero_zeros.values()[b]
return k_out
else:
b=np.random.randint(num)
k_out=out_degrees[b]
return k_out
N=200
g=gt.random_graph(N, lambda:(sample_in(), sample_out()),
model="constrained-configuration", directed=True)
I also tried sampling from a list of tuples as you have mentioned before in
the forum, but I didn't receive any results, as the tuples randomly drawn
from my list might not be combinable.
degs=[(7,1),(4,3),(5,6),(2,4),(6,8),(2,0),(3,5),(0,3),(2,7),(2,1)]
g = gt.random_graph(4, lambda i: degs[i], directed=True)
- Is there any option I could active that would help me in those cases I
described above?
- Is there a better way how to create representative small networks?
Any help on that issue will be much appreciated.
Best wishes,
Jana
--
Sent from: http://main-discussion-list-for-the-graph-tool-project.982480.n3.nabble.com/