import metaknowledge as mk
import networkx as nx

"""
Explanation: Making a network
For this class most of the types of network you will want to make can be produced by metaknowledge. The first three co-citation network, citation network and co-author network are specialized versions of the last three one-mode network, two-mode network and multi-mode network.
First we need to import metaknowledge and because we will be dealing with graphs the graphs package networkx as should be imported
End of explanation
"""


import matplotlib.pyplot as plt
%matplotlib inline
import metaknowledge.contour.plotting as mkv

"""
Explanation: And so we can visualize the graphs
End of explanation
"""


RC = mk.RecordCollection('../savedrecs.txt')

"""
Explanation: Before we start we should also get a RecordCollection to work with.
End of explanation
"""


coCites = RC.networkCoCitation()
print(mk.graphStats(coCites, makeString = True)) #makestring by default is True so it is not strictly necessary to include

"""
Explanation: Now lets look at the different types of graph.
Making a co-citation network
To make a basic co-citation network of Records use networkCoCitation().
End of explanation
"""


coCiteJournals = RC.networkCoCitation(nodeType = 'journal', dropNonJournals = True)
print(mk.graphStats(coCiteJournals))

"""
Explanation: graphStats() is a function to extract some of the statists of a graph and make them into a nice string.
All the graphs metaknowledge use are networkx graphs, a few functions to trim them are implemented in metaknowledge, here is the example section, but many useful functions are implemented by it. Read the documentation here for more information.
The networkCoCitation() function has many options for filtering and determining the nodes. The default is to use the Citations themselves. If you wanted to make a network of co-citations of journals you would have to make the node type 'journal' and remove the non-journals.
End of explanation
"""


nx.draw_spring(coCiteJournals)

"""
Explanation: Lets take a look at the graph after a quick spring layout
End of explanation
"""


citationsA = RC.networkCitation(nodeType = 'year', keyWords = ['A'])
print(mk.graphStats(citationsA))

nx.draw_spring(citationsA, with_labels = True)

"""
Explanation: A bit basic but gives a general idea. If you want to make a much better looking and more informative visualization you could try gephi or visone. Exporting to them is covered below in Exporting graphs.
Making a citation network
The networkCitation method is nearly identical to networkCoCitation in its parameters. It has one additional keyword argument directed that controls if it produces a directed network.
One small example is still worth providing. If you want to make a network of the citations of years by other years and have the letter 'A' in them then you would write:
End of explanation
"""


coAuths = RC.networkCoAuthor()
print(mk.graphStats(coAuths))

"""
Explanation: Making a co-author network
The coAuthNetwork() function produces the co-authorship network of the RecordCollection as is used as shown
End of explanation
"""


minWeight = 2
maxWeight = 10
mk.dropEdges(coAuths, minWeight, maxWeight, dropSelfLoops = True)
print(mk.graphStats(coAuths))

"""
Explanation: Post processing graphs
If you wish to apply a well known algorithm or process to a graph networkx is a good place to look as they do a good job at implementing  them.
One of the features it lacks though is pruning of graphs, metaknowledge has these capabilities. To remove edges outside of some weight range, use dropEdges(). For example if you wish to remove the self loops, edges with weight less than 2 and weight higher than 10 from coAuths.
End of explanation
"""


mk.dropNodesByDegree(coAuths, 1)
print(mk.graphStats(coAuths))

"""
Explanation: Then to remove all the isolates, i.e. nodes with degree less than 1, use dropNodesByDegree()
End of explanation
"""


nx.draw_spring(coAuths)

"""
Explanation: After the processing it looks like
End of explanation
"""


mk.writeGraph(coAuths, "FinalJournalCoCites")

"""
Explanation: Hm, it looks a bit thinner. Using a visualizer will make the difference a bit more noticeable.
Exporting graphs
Now you have a graph the last step is to write it to disk. networkx has a few ways of doing this, but they tend to be slow. metaknowledge can write an edge list and node attribute file that contain all the information of the graph. The function to do this is called writeGraph(). You give it the start of the file name and it makes two labeled files containing the graph.
End of explanation
"""


FinalJournalCoCites = mk.readGraph("FinalJournalCoCites_edgeList.csv", "FinalJournalCoCites_nodeAttributes.csv")
print(mk.graphStats(FinalJournalCoCites))

"""
Explanation: These files are simple CSVs an can be read easily by most systems. If you want to read them back into Python the readGraph() function will do that.
End of explanation
"""


