Closed jolespin closed 4 years ago
Hi!
Good question.
So you should be able to do
import teneto
tnet = TemporalNetwork(....)
tnet.plot('graphlet_stack_plot')
But it looks like my recent changes to increase speed are breaking something here. Oops!
So if you have a TemporalNetwork object, the best thing to do until I fix this is:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1)
# this creates a numpy array of node,node,time (all teneto functions work with this)
network = tnet.df_to_array()
teneto.plot.graphlet_stackplot(network, ax)
Typing fig.show(), fig.savefig() will get or save the figure for you. Now I just noticed that in more recent versions of matplotlib it is making an empty figure as well. So don't be alarmed if that happens.
So you helped me identify 2 bugs. Thank you! And hopefully this workaround works for you until I get around to solving them.
Thanks! I thought I tried that but apparently not.
My networks are fully connected but weighted, is there a way to show the weights?
tnet = temporalgraph.teneto_network_
print(tn)
# <teneto.classes.network.TemporalNetwork object at 0x12e032a20>
fig, ax = plt.subplots()
# this creates a numpy array of node,node,time (all teneto functions work with this)
network = tnet.df_to_array()
teneto.plot.graphlet_stack_plot(network, ax, vminmax=[-1,1])
I think you have a lot of nodes and the border between each square is overwhelming the figure. Try:
teneto.plot.graphlet_stack_plot(network, ax, vminmax=[-1,1], borderwidth=0)
I have 54
nodes which are essentially the 4 iris features and 50 noise variables.
I got the following error:
teneto.plot.graphlet_stack_plot(network, ax, vminmax=[-1,1], borderwidth=0)
<teneto.classes.network.TemporalNetwork object at 0x12e032a20>
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-270-14b23efc9796> in <module>
8
9
---> 10 teneto.plot.graphlet_stack_plot(network, ax, vminmax=[-1,1], borderwidth=0)
~/anaconda/envs/µ_env/lib/python3.6/site-packages/teneto/plot/graphlet_stack_plot.py in graphlet_stack_plot(netin, ax, q, cmap, gridcolor, borderwidth, bordercolor, Fs, timeunit, t0, sharpen, vminmax)
175 figmattmp_withborder = np.zeros(
176 [figmattmp.shape[0] + (qb * 2), figmattmp.shape[1] + (qb * 2), 3]) + (np.array(bordercolor) * 255)
--> 177 figmattmp_withborder[qb:-qb, qb:-qb, :] = figmattmp
178
179 # Make corners rounded. First make a circle and then take the relevant quarter for each corner.
ValueError: could not broadcast input array from shape (800,800,3) into shape (0,0,3)
If I increase the figsize would that help you think?
Sorry, I forgot borderwidth can't be set to 0 for reasons I have forgotten (but that I noted in the documentation). Set it to 0.1 or something small.
I'm getting the same error, it looks like anytihng smaller than 1
throws the error.
teneto.plot.graphlet_stack_plot(network, ax, vminmax=[-1,1], borderwidth=1-1e-5)
didn't work.
Yeah. It's been a while since I used this function :)
Does borderwidth=1 improve the figure at least? The default is 2.
Haha, I understand. I just found your teneto
paper in Network Neuroscience
and I learned a lot! Looking forward to applying this to some microbiome datasets.
I tried the following but to no avail:
Let me do a little bit of testing and I will get back to you.
So I was able to replicate you problem with any big network (think I had only done 35 nodes before)
So I've just updated the teneto from the main branch, so you'll have to update:
pip install -U git+http://github.com/wiheto/teneto
I can now do:
import matplotlib.pyplot as plt
import teneto
a = teneto.generatenetwork.rand_binomial([60,60,3],0.5)
teneto.plot.graphlet_stack_plot(a,ax, borderwidth=0)
And it now makes:
And before I got the same as you.
Changing the colormap (cmap) will make the white parts less ugly and useful for weighted networks. Also, you may want to look into the parameter q. The default is 10, increasing this will generate higher quality bitmaps (each snapshot is converted into bitmap in order to be scaled to look 3D). Increasing this parameter to 15 or 20 will make the figure look nicer, but will use more RAM.
This was the first function I made for teneto back in 2016-ish. Some improvements can definitely be added to it. If there are any features you'd rather have, let me know.
Thank you! This will be really useful moving forward.
While exploring your package, I've thought of a few features that would make it a little more broad use:
(1) Build on top of networkx
to export networkx
graph objects and integrate into the rest of SciPy
ecosystem;
(2) Include option for non-integer node labels;
(3) Add weighted edges (this would be huge!) to the slice plots;
(4) Maybe a stacked network feature (networkx
would help with this using the pos
layouts);
In terms of this plot, it may be useful to have the following:
(1) heatmap_kws
where a user can define things like linewidth
, edgecolor
, etc.
(2) Maybe a colorbar on the bottom?
(3) Other rotations like this example?
Thanks for the input.
(1) there is teneto.utils.tnet_to_nx() but I don't think I've made a from_nx() and should be added. Making these more prominent feature/part of TemporalNetowrk object is on the long to-do list.
(2) Non-integer node labels are possible as meta-data that get carried over to the plots, just not part of the network data itself. I admit this could be better or be more integrated. I'll keep that in mind.
(3) Will do. That's a relatively easy one.
Regarding the other points, I want to completely remake all the visualizations with greater flexibility and add some new ideas and inspiration I've got since I made them. So these are all useful suggestions that I'll keep in mind.
I'm currently rewriting a lot of the other backend stuff at the moment regarding workflows and neuroimaging that's about to be released. Once I've done that, I'll hopefully get around to visualizations again.
I had a question about the slice_plot
. I just realized the point [3] about slice plots above was already implemented!
However, I had a question about the following:
It appears that the nodes are node_index + 1
. Is this true?
For example, is my node=0
represented as node=1
, ..., node=3
as node=4
?
data = {'i': {0: 1, 1: 1, 2: 1, 3: 0, 4: 0, 5: 2, 6: 1, 7: 1, 8: 1, 9: 0, 10: 0, 11: 2, 12: 1, 13: 1, 14: 1, 15: 0, 16: 0, 17: 2, 18: 1, 19: 1, 20: 1, 21: 0, 22: 0, 23: 2, 24: 1, 25: 1, 26: 1, 27: 0, 28: 0, 29: 2}, 'j': {0: 0, 1: 2, 2: 3, 3: 2, 4: 3, 5: 3, 6: 0, 7: 2, 8: 3, 9: 2, 10: 3, 11: 3, 12: 0, 13: 2, 14: 3, 15: 2, 16: 3, 17: 3, 18: 0, 19: 2, 20: 3, 21: 2, 22: 3, 23: 3, 24: 0, 25: 2, 26: 3, 27: 2, 28: 3, 29: 3}, 't': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 1, 7: 1, 8: 1, 9: 1, 10: 1, 11: 1, 12: 2, 13: 2, 14: 2, 15: 2, 16: 2, 17: 2, 18: 3, 19: 3, 20: 3, 21: 3, 22: 3, 23: 3, 24: 4, 25: 4, 26: 4, 27: 4, 28: 4, 29: 4}, 'weight': {0: 0.2659470401637537, 1: 0.0039524797711067506, 2: 0.3923470839260313, 3: 0.49102741918275905, 4: 0.2262588904694168, 5: 0.1710384068278805, 6: 0.1923126782473425, 7: 0.12781954887218044, 8: 0.39298215657816105, 9: 0.46772102670469273, 10: 0.4094595748313839, 11: 0.42440023905062746, 12: 0.10234185290365067, 13: 0.05244268839774458, 14: 0.05199555720103665, 15: 0.5472686733556299, 16: 0.4514328026656794, 17: 0.38736764161421694, 18: 0.0645016034793305, 19: 0.1498045073145016, 20: 0.30735054419264946, 21: 0.5913901632348235, 22: 0.5225533959711175, 23: 0.44053414939490887, 24: 0.1874118285404232, 25: 0.010607704829083018, 26: 0.2169332366301485, 27: 0.5246201844818231, 28: 0.18150933312974768, 29: 0.3461465053250372}}
df_network = pd.DataFrame(data)
network = np.asarray([[[0. , 0. , 0. , 0. , 0. ],
[0.26594704, 0.19231268, 0.10234185, 0.0645016 , 0.18741183],
[0.49102742, 0.46772103, 0.54726867, 0.59139016, 0.52462018],
[0.22625889, 0.40945957, 0.4514328 , 0.5225534 , 0.18150933]],
[[0.26594704, 0.19231268, 0.10234185, 0.0645016 , 0.18741183],
[0. , 0. , 0. , 0. , 0. ],
[0.00395248, 0.12781955, 0.05244269, 0.14980451, 0.0106077 ],
[0.39234708, 0.39298216, 0.05199556, 0.30735054, 0.21693324]],
[[0.49102742, 0.46772103, 0.54726867, 0.59139016, 0.52462018],
[0.00395248, 0.12781955, 0.05244269, 0.14980451, 0.0106077 ],
[0. , 0. , 0. , 0. , 0. ],
[0.17103841, 0.42440024, 0.38736764, 0.44053415, 0.34614651]],
[[0.22625889, 0.40945957, 0.4514328 , 0.5225534 , 0.18150933],
[0.39234708, 0.39298216, 0.05199556, 0.30735054, 0.21693324],
[0.17103841, 0.42440024, 0.38736764, 0.44053415, 0.34614651],
[0. , 0. , 0. , 0. , 0. ]]])
print("Nodes:", np.unique(df_network.loc[:,["i","j"]].values.ravel()))
with plt.style.context("seaborn-white"):
fig, ax = plt.subplots()
teneto.plot.slice_plot(network, ax, plotedgeweights=True, cmap=plt.cm.seismic, nodesize=200)
Yes. (Sorry for late answer)
There’s an argument called timelabels if you want to change it to a list of strings.
Like I’ve said these plotting functions are a little old and I need to update them to be a little more pythonic in places. But I reasoned most want their first time point to be called “1” if integers, hence the implementation.
26 aug. 2019 kl. 12:04 skrev Josh L. Espinoza notifications@github.com:
I had a question about the slice_plot:
It appears that the nodes are node_index + 1. Is this true?
For example, is my node=0 represented as node=1, ..., node=3 as node=4?
data = {'i': {0: 1, 1: 1, 2: 1, 3: 0, 4: 0, 5: 2, 6: 1, 7: 1, 8: 1, 9: 0, 10: 0, 11: 2, 12: 1, 13: 1, 14: 1, 15: 0, 16: 0, 17: 2, 18: 1, 19: 1, 20: 1, 21: 0, 22: 0, 23: 2, 24: 1, 25: 1, 26: 1, 27: 0, 28: 0, 29: 2}, 'j': {0: 0, 1: 2, 2: 3, 3: 2, 4: 3, 5: 3, 6: 0, 7: 2, 8: 3, 9: 2, 10: 3, 11: 3, 12: 0, 13: 2, 14: 3, 15: 2, 16: 3, 17: 3, 18: 0, 19: 2, 20: 3, 21: 2, 22: 3, 23: 3, 24: 0, 25: 2, 26: 3, 27: 2, 28: 3, 29: 3}, 't': {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 1, 7: 1, 8: 1, 9: 1, 10: 1, 11: 1, 12: 2, 13: 2, 14: 2, 15: 2, 16: 2, 17: 2, 18: 3, 19: 3, 20: 3, 21: 3, 22: 3, 23: 3, 24: 4, 25: 4, 26: 4, 27: 4, 28: 4, 29: 4}, 'weight': {0: 0.2659470401637537, 1: 0.0039524797711067506, 2: 0.3923470839260313, 3: 0.49102741918275905, 4: 0.2262588904694168, 5: 0.1710384068278805, 6: 0.1923126782473425, 7: 0.12781954887218044, 8: 0.39298215657816105, 9: 0.46772102670469273, 10: 0.4094595748313839, 11: 0.42440023905062746, 12: 0.10234185290365067, 13: 0.05244268839774458, 14: 0.05199555720103665, 15: 0.5472686733556299, 16: 0.4514328026656794, 17: 0.38736764161421694, 18: 0.0645016034793305, 19: 0.1498045073145016, 20: 0.30735054419264946, 21: 0.5913901632348235, 22: 0.5225533959711175, 23: 0.44053414939490887, 24: 0.1874118285404232, 25: 0.010607704829083018, 26: 0.2169332366301485, 27: 0.5246201844818231, 28: 0.18150933312974768, 29: 0.3461465053250372}} df_network = pd.DataFrame(data) network = np.asarray([[[0. , 0. , 0. , 0. , 0. ], [0.26594704, 0.19231268, 0.10234185, 0.0645016 , 0.18741183], [0.49102742, 0.46772103, 0.54726867, 0.59139016, 0.52462018], [0.22625889, 0.40945957, 0.4514328 , 0.5225534 , 0.18150933]],
[[0.26594704, 0.19231268, 0.10234185, 0.0645016 , 0.18741183], [0. , 0. , 0. , 0. , 0. ], [0.00395248, 0.12781955, 0.05244269, 0.14980451, 0.0106077 ], [0.39234708, 0.39298216, 0.05199556, 0.30735054, 0.21693324]], [[0.49102742, 0.46772103, 0.54726867, 0.59139016, 0.52462018], [0.00395248, 0.12781955, 0.05244269, 0.14980451, 0.0106077 ], [0. , 0. , 0. , 0. , 0. ], [0.17103841, 0.42440024, 0.38736764, 0.44053415, 0.34614651]], [[0.22625889, 0.40945957, 0.4514328 , 0.5225534 , 0.18150933], [0.39234708, 0.39298216, 0.05199556, 0.30735054, 0.21693324], [0.17103841, 0.42440024, 0.38736764, 0.44053415, 0.34614651], [0. , 0. , 0. , 0. , 0. ]]])
print("Nodes:", np.unique(df_network.loc[:,["i","j"]].values.ravel()))
with plt.style.context("seaborn-white"): fig, ax = plt.subplots() teneto.plot.slice_plot(network, ax, plotedgeweights=True, cmap=plt.cm.seismic, nodesize=200)
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.
So the errors here for tnet.TemporalNetwork was actually fixed a while ago. The following now works:
import teneto
tnet.generatenetwork('rand_binomial', size=(5,5), prob=(0.5, 0.1))
tnet.plot('graphlet_stack_plot')
as does
import teneto
import matplotlib.pyplot as plt
tnet.generatenetwork('rand_binomial', size=(5,5), prob=(0.5, 0.1))
fig, ax = plt.subplots(1)
tnet.plot('graphlet_stack_plot', ax=ax)
Which was the original bug reported here.
The making more flexible stacking plots is on a feature todo list.
I have a weighted undirected network with 3 timepoints. How can I use this with your plotting functions? It seems the
TemporalNetwork
is the main object for this package so I'm confused on how I can use this with the plotting functions.