User Tools

Site Tools


alelievre_cdjemiel_lmarmiesse:aurelie_lelievre_christophe_djemiel_lucas_marmiesse

Visual Analytics Course

Bordeaux roadmap / Aurélie Lelièvre, Christophe Djemiel & Lucas Marmiesse's corner

Notre présentation est optimisé pour les navigateurs Safari et Chrome.djemiel_lelievre_marmiesse.tar.gz

Présentation su sujet

Nous avons choisi de travailler sur le jeu de donnée “High-energy physics theory citation network” (http://snap.stanford.edu/data/cit-HepTh.html) issu du Stanford Large Network Dataset Collection. Ces données contiennent des informations sur 27,770 articles traitant de la physique des particules ainsi que les liens de citations entre ces articles. Ces données couvrent la période de janvier 1993 à avril 2003.

Ces données sont séparées en plusieurs fichiers :

- Un fichier contenant un graphe dont les nœuds représentent les articles et les arêtes représentant les citations. Lorsqu’un article i cite un article j, le graphe contient une arête orientée de i à j. Si un article cite ou est cité par un article qui n'est pas présent dans le jeu de données, le graphe ne contient pas d'information à ce sujet. Le jeu de données choisi contient un graphe représentant les citations entre des articles de physique. Lorsqu’un article i cite un article j, le graphe contient une arête orientée de i à j. Si un article cite ou est cité par un article qui n'est pas présent dans le jeu de données, le graphe ne contient pas d'information à ce sujet. Le graphe possède au total 27770 noeuds et 352807 arêtes.

- Des fichiers texte classés par année pour chaque article, ces fichiers contiennent les informations suivantes :

  • Date de parution de l'article
  • Titre
  • Journal de la publication
  • Les auteurs
  • Un résumé

Exemple d'un fichier :

------------------------------------------------------------------------------
\\
Paper: hep-th/9301018
From: nakanisi@string.harvard.edu (Tomoki Nakanisi)
Date: Thu, 7 Jan 93 00:00:12 -0500   (19kb)
Date (revised): Wed, 27 Jan 93 10:10:31 -0500

Title: Characters in Conformal Field Theories from Thermodynamic Bethe Ansatz
Authors: A.Kuniba, T.Nakanishi and J.Suzuki
Comments: 12 pages, harvmac, 1 postscript figure file, (some confusion on PF
  Hilbert space was modified) HUTP-92/A069
Journal-ref: Mod. Phys. Lett. A8 (1993) 1649-1660
\\
  We propose a new $q$-series formula for a character of parafermion conformal
field theories associated to arbitrary non-twisted affine Lie algebra
$\widehat{g}$. We show its natural origin from a thermodynamic Bethe ansatz
analysis including chemical potentials.
\\

- Un fichier contenant seulement les dates de parution des articles

A partir de ces données, nous souhaitons répondre aux questions suivantes :

  • Comment mettre en évidence des différences entre les auteurs et les journaux ?
  • Quels sont les thèmes les plus abordés dans les articles ?
  • Est ce qu'il existe des communautés d'auteurs ?
  • Comment ces données évoluent-elles dans le temps ?

Nettoyage des données

Dans un premier temps nous avons procédé à un nettoyage afin de d'homogénéiser les données récupérées et de faciliter nos analyses.

Nous avons vérifié si tous les articles présents dans le fichier décrivant le graphe avaient bien un fichier d'information correspondant. Ceci nous a permis de nous rendre compte que l'écriture de certains noeuds du graphe n'était pas correcte, en effet, lorsque les numéros des articles commencaient par un ou plusieurs zéros, ces zéros n'était pas présents, nous les avons donc ajouté pour faire correspondre les nœuds du graphe aux noms des fichiers contenant les informations sur les articles .

Nous avons également remarqué que de nombreux nœuds du graphes n'avaient pas de fichier d'informations associés. Inversement certaines fichier d'informations ne correspondaient à rien dans le graphe. Il existait également des articles qui se citaient eux-mêmes.

Nous avons décidé de supprimer ces données car elles auraient gêné notre analyse.

Pour ce qui est du formatage des données, nous avons fait en sorte de gérer le mieux possible les différences d'écriture entre les fichiers d'informations. En effet, ces fichiers différent l'un l'autre dans la façon dont les données sont représentées.

Les auteurs de chaque article peuvent êtres écrits de manières différents :

  • Le mot clé de la ligne correspondant aux auteurs peut être “Author” ou “Authors”.
  • Les auteurs peuvent être séparés par une virgule, par le mot “and” …
  • Certains auteurs sont désignés par l'initiale de leur nom ou leur nom entier

Nous avons récupéré les auteurs en tenant compte de cela, cependant, nous n'avons pas pu résoudre tous ces problèmes. Lorsque les noms sont écrits de manière différentes, nous ne pouvions pas déterminer si ils correspondaient aux mêmes auteurs ou non.

Certains articles n'avaient pas d'informations sur le journal dans lequel ils ont été publiés, nous ne les avons pas pris en compte lors de nos analyses sur les journaux. De plus, l'écriture des journaux contenait les numéros des publications (exemple : JHEP 0202 (2002) 007), nous avons donc pris en compte seulement le nom du jounal. Nous avons été confronté au même problème qu'avec les auteurs car les journaux n'étaient pas toujours de la même manière, nous ne pouvions pas déterminer s'il s'agissaient d'écritures différentes ou de journaux différents.

Nous avons ensuite vérifié si le graphe était connexe, et cela nous a montré qu'il était composé d'une grosse composante connexe, et de nombreuses autres petites composantes d'un ou deux nœuds. Nous gardons le gros graphe connexe qui nous permettra d'analyser les relations entre des communautés d'auteurs par exemple .

Après ce nettoyage, notre graphe compte 16363 nœuds et 152839 arêtes.

Visualisation

Analyse lexicale

Le but

Une analyse lexicale consiste à rechercher les mots les plus utilisés dans un corpus. Dans notre cas, nous nous sommes intéressés à l'étude des titres et des résumés d'articles. Il y a plusieurs intérêt à faire une analyse lexicale. La première est d'extraire les thématiques principales et de connaître les fréquences des mots. La seconde est de réaliser de façon synthétique et visuelle un nuage de mot-clés afin de résumer cette analyse. De nombreuses études ont été faites par Jean Véronis http://blog.veronis.fr/.

Le déroulement

L'analyse lexicale consiste à décomposer une chaîne de caractères en unités ou entités lexicales, aussi appelées tokens en anglais. Il faut ensuite calculer une distribution sur le corpus puis réaliser une étape de filtrage des mots afin d'éliminer ceux qui participent peu. Dans un dernier temps, pour faciliter l'analyse et avoir un résumé rapide, nous visualisons les différents mots-clés les plus fréquents.

La visualisation

La façon la plus courante de visualiser une analyse lexicale est d'utiliser la méthode dite de Nuage de mot-clés. En effet, plus un mot-clé est cité plus il apparaîtra en gros dans le nuage. Il suffit d'augmenter la police de caractères. Il suffit ensuite de générer une image au format jpeg/png ou sous la forme d'une page web au format HTML. Cette dernière peut être plus informative car nous pouvons la rendre interactive car lorsqu'on clique sur un mot clé on peut accéder à différentes informations comme par exemple sa fréquence ou encore dans quel corpus il est présent.

Conception

Il existe différentes méthodes, logiciels ou algorithmes pour réaliser une analyse lexicale. Nous avons opté pour une méthode libre qui s'inspire de l'outil Wordle http://www.wordle.net. Nous avons trouvé une bibliothèque Python qui permet de réaliser cette étude. Il s'agit de la la bibliothèque PyTagCloud. Elle nécessite les dépendances pygame http://www.pygame.org/news.html et simplejsonhttp://pypi.python.org/pypi/simplejson/ et est disponible ici https://github.com/atizo/PyTagCloud.

Réalisation

Cette bibliothèque s'inspire de l'algorithme de Wordle qui se déroule ainsi :

  • Compter les mots
  • Filtrer les mots faiblement représentés
  • Trier les mots par ordre décroissant d'apparition
  • Garder le haut de la pile
  • Assigner une taille proportionnellement à son nombre.

Le script réalisé va extraire et classer les mots-clés de façon identique à celle de la bibliothèque Python NLTK http://nltk.org/.

Example : (Theory: 255, String: 255)

Résultats

Nous pouvons remarquer qu'il y a une correlation entre les thèmes des titres et ceux des résumés. Les mot-clés les plus présents sont theory,string,gauge et quantum. Ces sujets de physique quantique, la théorie des cordes et de Gauge correspondent aux thèmes les plus abordés durant les années 90. En effet nous constatons la présence de ces mots-clés durant toutes ces années.

 Mots-clés du résumé de l'année 1994

 Mots-clés du résumé de l'année 1998

 Mots-clés du résumé de l'année 2002

Le script générant ces images est disponible en annexe sous le nom tagCloud.py

Analyses en fonction du temps

Calculs sur les auteurs

Nous nous sommes ensuite penchés sur différentes analyses concernant les auteurs des articles. Notre but était de faire ressortir plusieurs statistiques et informations intéréssantes les concernant. Tout d'abord, nos données permettent de calculer le nombre d'articles ayant été écrits (ou co-écrits) par un auteur en particulier. Du fait que nos donnés renseignent également la date de publication de chaque article, il est possible faire ce calcul sur des intervalles de temps et d'en observer l'évolution. De plus pour aller plus loin, nous avons décidé de lier cela aux liens entre les articles en calculant la somme du nombre de références vers l'ensemble de ses artciles pour chaque auteur. En effet il nous semble plus cohérent pour expliquer l'influence d'un auteur de prendre en compte non seulement le nombre de publications mais également le nombre de références vers ses publications. Nous avons également calculé un rapport représentant le nombre de référence par publication pour rendre compte de la popularité d'un auteur.

Pour effectuer cela nous avons réalisé un script python qui parse les fichier sources, sauvegarde dans la mémoire vive les données importantes, et génère ensuite un fichier au format .tlp visualisable ensuite par tulip. Dans un premier temps, nous parsons le fichier contenant tous les liens en récuperant tous les liens entre les articles. Notre algorithme parcourt ensuite tous les fichiers d'information pour récupérer une liste d'auteur pour chaque article, ce qui nous permet de compter le nombre d'article par auteur. Il compare ensuite ces listes avec les liens entre les article pour déterminer le nombre de références vers un auteur ainsi que le nombre de référence par article publié. Ce parcours se fait année par année ce qui nous permet de générer une visualisation (en générant un fichier .tlp) par année. Nous additionnant également toutes les données pour obtenir un résultat total sur l'ensemble des années (de 1993 à 2003).

Le script est disponible à la fin de la page sous le nom “Auteurs.py”

Résultats

l’abscisse correspond au nombre de publication de l'auteur et l'ordonnée aux nombre de référence vers les articles de cet auteur. Le dégradé de couleur correspond lui au rapport publication/article publié, plus le cercle est foncé, plus l'auteur a de référence vers lui par article.

19951999Total

Cette visualisation permet de repérer rapidement les auteurs influents, et les auteurs qui publient beaucoup. On voit donc que l'auteur Edward Witten sort du lot et semble être l'auteur le plus influent dans le domaine de la physique théorique sur cette période. On peut cependant remarquer qu'il n'est pas l'auteur ayant rédigé le plus d'articles, ceci revient à H.Lu.

Le dégradé de couleur que nous avons choisi nous permet de compléter cette analyse en mettant en valeur des auteurs qui peuvent être influents sans avoir rédigé beaucoup d'articles, ou le contraire, comme pour H.Lu, qui a rédigé beaucoup mais semble rester moins influent que beaucoup d'autres.

Nous avons effectués le même travail en ce qui concerne les journaux en changeant légèrement le script. Le résultat est le suivant :

On voit également ressortir les journaux les plus populaires.

Par la suite, en ce qui concerne les auteurs, nous avons utilisé les données calculées pour chaque année afin de créer un visualisation animée grâce à Tulip. En effet nous faisons varier les coordonnées des points en fonction du temps de 1993 à 2003. Comme la mise à jour des coordonnées d'environ 20 000 points à la fois (le nombre d'auteurs) rendait la visualisation trop lente et saccadée, nous nous somme limités aux auteurs les plus influents, et nous avons ensuite sélectionné une centaine d'autres auteurs aléatoirement à afficher sur la vidéo.

La vidéo est disponible à l'adresse suivante http://www.youtube.com/watch?v=bbi0EEi7GrM

le fichier tlp utilisé “animation.tlp” et le script “animation.py” sont présents en annexe. Le script “animation” marche en chargeant les coordonnées qui sont situés dans des fichiers générés par le script “generereCoord.py” également disponible en annexe (ce fichier est basé sur ““Auteur.py”).

Analyse des communautés d'auteurs

Le but

Nous avons voulu déterminer s'ils existait des communautés d'auteurs c'est à dire des groupes dans lesquels des auteurs se citent entre eux. S'il existe de telles communautés nous souhaitons visualiser le nombre de fois ou les auteurs de cette communautés sont cités, le nombre d'auteur de cette communauté ainsi que le nombre de publications de ses auteurs. L'intérêt de cette visualisation est d'observer les communautés d'auteurs qui ont le plus d'influence (c'est à dire qui sont le plus souvent cités).

La visualisation

Nous avons affichés les communautés d'auteur sous forme de cercles, chaque communauté à une couleur différente aléatoire qui permet de mieux différencier les communautés. Chacun de ces cercles contient un ensemble de points qui sont placés aléatoirement dans le cercle , chaque point correspondant à un auteur. Ces points ont la même couleur que le cercle auquel ils appartiennent avec une opacité plus élevée pour mieux les visualiser. Les cercles sont disposés en ligne et leur espacement est constant, ils n'ont pas d'intersection. La taille du cercle est proportionnelle au nombre de publications de cette communauté. Le chiffre au centre du cercle représentant la communauté représente le nombre d'auteur de cette communauté.

Réalisation

A l'aide d'un script Python, nous avons déterminé les communautés par rapport à un auteur. Pour cela, nous sélectionnons un auteur et recherchons parmi ceux qu'il cite, ceux qui le citent aussi. Ceci permet de créer des communautés d'auteurs centrés sur les auteurs sélectionnes dans un premiers temps.

Le script permet de créer une visualisation de la taille voulue (avec plus ou de communautés représentées)

Le script est donné en annexe sous le nom “communaute.py”

Résultats

Nous obtenons les visualisations suivantes pour 200 communautés et 25 communautés :

Conclusion

Tout au long de notre projet, nous avons dû faire face à différents problèmes. Tout d'abord, les données que nous avons choisi contiennent certaines incohérences et sont incomplètes. En effet les fichiers de description ne sont pas correctement normalisés (par exemple des auteurs cités différemment dans deux fichiers), ce qui amène fatalement des erreurs même si nous avons essayé de prendre cela en compte. De plus la grande taille des informations présentes engendre à la fois des temps de calcul plus longs, et une plus grande difficulté à extraire l'essentiel et le plus pertinent à représenter.

Nous avons dû faire des choix parmi les multiples questions possibles.

Nous avons donc utilisé à la fois les liens entre les articles, mais également le plus de données possible venant des fichiers descriptifs. En effet, nous avons pu représenter aussi bien les auteurs, les journaux, les textes ainsi que les dates. En effet cette composante temporelle permet une dimension supplémentaire que nous avons voulu faire ressortir sur une vidéo. Ceci nous a donc permis de mettre en évidence les auteurs qui publient le plus, les plus influents, les journaux les plus réputés et les thématiques les plus souvent reprises dans les articles.

De plus, une analyse un peu plus poussée nous a permis de trouver des communautés d'auteurs et de les comparer. Ces résultats ne représentent qu'une possibilité parmi d'autres de mettre en commun différents auteurs.

Devant les nombreuses questions que pose ce sujet, d'autres aspects auraient pu être envisagés. Par exemple, une analyse plus avancée des communautés (en tenant compte par exemple des journaux, des années de publication, ou des thèmes abordés), permettait de les affiner.

Annexe

Liste de scripts et fichier utiles

Auteurs.py
import os
 
dicoAuteursTotal={}#contient en clef l'auteur, et en valeur un tableau avec en 0 : nb de publi en 1 le nb de ref vers lui
 
dicoPubli={}#cle : artcile, valeur : liste des artciles qui le citent
 
#fonction qui exprte en .tlp
def toTlp(dicoAuteurs,out,publimax,refmax,rapportmax):
	f = open (out,"w")
 
	rapportTotal=float(refmax/publimax)
 
	facteurMultiplicateur=65/rapportTotal
 
	f.write("(tlp \"2.3\"\n")
 
	f.write("(nb_nodes " + str(len(dicoAuteurs)) + ")\n");
	f.write("(nodes 0.." + str(len(dicoAuteurs) - 1) + ")\n");
	f.write("(nb_edges 0)\n");
 
	#on ecrit le label
	f.write("(property  0 string \"viewLabel\"\n");
	f.write("(default \"\" \"\")\n");
 
	cpt=0
	for author in dicoAuteurs:
		f.write("(node "+str(cpt)+" \""+author.replace("("," ").replace(")"," ").replace("&"," ").replace(";"," ").replace("\"","")+"\")\n")
		cpt+=1
 
	f.write(")\n")
 
 
 
	#on met les coordonnees
	f.write("(property  0 layout \"viewLayout\"\n");
	f.write("(default \"(0,0,0)\" \"()\")");
 
	cpt=0
	for author in dicoAuteurs:
		f.write("(node "+str(cpt)+" \"("+str((dicoAuteurs[author][0]/120.0)*15000)+","+str((dicoAuteurs[author][1]*facteurMultiplicateur))+",0)\")\n")
		cpt+=1
 
	f.write(")\n")
 
 
 
	dicoCouleurs={}
	dicoCouleurs[0]=[251,208,151]
	i=1
	while i<10:
		dicoCouleurs[i]=[dicoCouleurs[i-1][0]-27,dicoCouleurs[i-1][1]-18,dicoCouleurs[i-1][2]-5]
 
		i+=1
 
	#on change les couleurs
	f.write("(property  0 color \"viewColor\"\n");
	f.write("(default \"(255,0,0,255)\" \"(0,0,0,255)\")");
 
	cpt=0
	for author in dicoAuteurs:
 
		rapport=dicoAuteurs[author][2]/float(rapportmax)*10.0
 
 
		if rapport==10.0:
			rapport=9.0
		bonIndice=int(rapport)
 
		if author=="EdwardWitten":
			print dicoAuteurs[author][1]
			print "refmax",refmax
			print "Rapport",rapport
			print "indice",bonIndice
 
		f.write("(node "+str(cpt)+" \"("+str(dicoCouleurs[bonIndice][0])+","+str(dicoCouleurs[bonIndice][1])+","+str(dicoCouleurs[bonIndice][2])+",255)\")\n")
 
		#~ if author=="EdwardWitten" or author=="H.Lu":
			#~ f.write("(node "+str(cpt)+" \"(51,255,51,255)\")\n")
		cpt+=1
 
	f.write(")\n")
 
 
	#on change la taille
	f.write("(property  0 size \"viewSize\"\n");
	f.write("(default \"("+str(publimax*2.5)+","+str(publimax*2.5)+",5)\" \"(200,200,0)\")\n");
	f.write(")\n")
 
 
	f.write("(property  0 int \"viewFontSize\"\n");
	f.write("(default \""+str(publimax*2.5)+"\" \""+str(publimax*2.5)+"\")\n");
	f.write(")\n")
 
	#on change la forme
	f.write("(property  0 int \"viewShape\"\n");
	f.write("(default \"2\" \"0\")\n");
	f.write(")\n")
 
	f.write(")")
	f.close()
 
 
 
 
f=open('data/Cit-HepTh.txt','r')
 
print 1
 
for ligne in f:
	if not "#" in ligne:
 
		if not dicoPubli.has_key(ligne.split()[0]):
			dicoPubli[ligne.split()[0]]=[]
		if not dicoPubli.has_key(ligne.split()[1]):
			dicoPubli[ligne.split()[1]]=[]
 
		dicoPubli[ligne.split()[1]].append(ligne.split()[0])
 
 
f.close()	
 
print 2
 
#~ print dicoPubli
 
annee=1993
 
while (annee<2004):
 
	dicoAuteurs={}#contient en clef l'auteur, et en valeur un tableau avec en 0 : nb de publi en 1 le nb de ref vers lui
 
	listeFichiers=os.listdir("data/"+str(annee))
 
	for fichier in listeFichiers:			
 
		f=open('data/'+str(annee)+"/"+fichier,'r')			
 
		article=fichier.replace(".abs","")		
 
		while article[0]=="0":
			article=article[1:]
 
		#si l'article n'etait pas dans la liste on l'ajoute
		if not dicoPubli.has_key(article):
			dicoPubli[article]=[]
 
 
		autheurs=[]	
 
		for ligne in f:
			if ("Authors:" in ligne) or ("Author:" in ligne):
				autheurs=ligne.split(":")[1].replace(" and ",",").replace("\n","").replace(" ","").split(",")
 
 
		#on parcourt les auteurs
 
		for autheur in autheurs:
 
			if autheur!="":	
				if not dicoAuteurs.has_key(autheur):
					dicoAuteurs[autheur]=[0,0,0]
 
				dicoAuteurs[autheur]=[dicoAuteurs[autheur][0]+1,dicoAuteurs[autheur][1],0]
 
				for art in dicoPubli[article]:
					dicoAuteurs[autheur]=[dicoAuteurs[autheur][0],dicoAuteurs[autheur][1]+1,0]
 
 
	#~ print len(dicoAuteurs)
	print len(dicoAuteurs)
 
 
	for autheur in dicoAuteurs:
		dicoAuteurs[autheur][2]=float(float(dicoAuteurs[autheur][1])/float(dicoAuteurs[autheur][0]))
 
 
	publimax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][0]>publimax:
			publimax=dicoAuteurs[a][0]
			autheurMax=a
 
	print autheurMax,publimax
 
 
	refmax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][1]>refmax:
			refmax=dicoAuteurs[a][1]
			autheurMax=a
 
	print autheurMax,refmax
 
	rapportmax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][2]>rapportmax:
			rapportmax=dicoAuteurs[a][2]
			autheurMax=a
 
	print autheurMax,rapportmax
 
	#~ print dicoAuteurs["H.Lu"]
	#~ print dicoAuteurs["EdwardWitten"]
	#~ print dicoAuteurs["StephenH."]
 
 
	print 3
 
	toTlp(dicoAuteurs,"authors"+str(annee)+".tlp",publimax,refmax,rapportmax)
 
 
	print annee	
	annee+=1
 
	for auteur in dicoAuteurs:
		if not dicoAuteursTotal.has_key(auteur):
			dicoAuteursTotal[auteur]=[0,0,0]
		dicoAuteursTotal[auteur]=[dicoAuteursTotal[auteur][0]+dicoAuteurs[auteur][0],dicoAuteursTotal[auteur][1]+dicoAuteurs[auteur][1],0]
 
 
 
for autheur in dicoAuteursTotal:
	dicoAuteursTotal[autheur][2]=float(float(dicoAuteursTotal[autheur][1])/float(dicoAuteursTotal[autheur][0]))
 
 
publimax = 0
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][0]>publimax:
		publimax=dicoAuteursTotal[a][0]
		autheurMax=a
 
print autheurMax,publimax
 
refmax = 0
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][1]>refmax:
		refmax=dicoAuteursTotal[a][1]
		autheurMax=a
 
print autheurMax,refmax
 
rapportmax = 0
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][2]>rapportmax:
		rapportmax=dicoAuteursTotal[a][2]
		autheurMax=a
 
print autheurMax,rapportmax
 
toTlp(dicoAuteursTotal,"authorsTotal.tlp",publimax,refmax,rapportmax)
animation.tlp
(tlp "2.3"
(nb_nodes 112)
(nodes 0..111)
(nb_edges 0)
(property  0 string "viewLabel"
(default "" "")
(node 0 "PKTownsend")
(node 1 "MasahiroShiroishi")
(node 2 "N.Seiberg")
(node 3 "TomohikoShibuya")
(node 4 "H.Y.Guo")
(node 5 "S.Yu.Gubanov")
(node 6 "ValeriV.Dvoeglazov ZacatecasUniversity")
(node 7 "Jean-Philippe")
(node 8 "S.Ferrara")
(node 9 "D-33501")
(node 10 "R.A.Leo")
(node 11 "L.Sch\ulke")
(node 12 "X.Liu")
(node 13 "BorisKors")
(node 14 "SeijiTerashima TokyoU. ")
(node 15 "M.Asorey")
(node 16 " RollandEotvosUniversity")
(node 17 "J.Lukierski Wroclaw ")
(node 18 "DmitriOrlov")
(node 19 "E.M.C.deAbreu")
(node 20 "M.A.Walton")
(node 21 "LeonardSusskind StanfordUniversity ")
(node 22 "OsamuTsuchiya")
(node 23 "D.G.C.McKeon UniversityofWesternOntario ")
(node 24 "J.Gonzalez")
(node 25 "RodolfoGambini")
(node 26 "J.--Q.Liang")
(node 27 "H.Lu")
(node 28 "KostasVlachos")
(node 29 "Guang-JiongNi")
(node 30 "AshokeSen")
(node 31 "CarlosA.R.Herdeiro")
(node 32 "Shin'ichiNojiri")
(node 33 "O.J.P.Eboli")
(node 34 "J.Novotny")
(node 35 "C.Castro")
(node 36 "C.N.Pope")
(node 37 "A.Sagnotti")
(node 38 "RainerScharf")
(node 39 "D.Varga")
(node 40 "P.Kosi{\'n}ski 1 ")
(node 41 "UT-diss-1994")
(node 42 "T.Shinohara ChibaUniv. ")
(node 43 "MarcusT.Grisaru")
(node 44 "G.Scharf")
(node 45 "TathagataDasgupta Cambridge ")
(node 46 "NoureddineMohammedi ToursUniversity")
(node 47 "J.D.M.Vianna")
(node 48 "YujiNakawaki")
(node 49 "M.A.Soloviev")
(node 50 "W.-S.Chung")
(node 51 "S.Dilcher")
(node 52 "C.Destri Universita'diMilano INFN")
(node 53 "RichardDawid")
(node 54 "IvanSchmidt")
(node 55 "L.C.Liu")
(node 56 "M.P.Mattis Los")
(node 57 "DouglasM.Eardley")
(node 58 "KirillKrasnov AEI ")
(node 59 "A.A.Tseytlin")
(node 60 "V\'{\i}ctorM.Villalba")
(node 61 "StephanD\urr")
(node 62 "PaulM.Saffin")
(node 63 "MosheRozali Rutgers ")
(node 64 "P.Maraner")
(node 65 "T.A.Larsson")
(node 66 "SergeiD.Odintsov")
(node 67 "C.Vafa")
(node 68 "AndreiGaliautdinov 2 ")
(node 69 "R.Pasquier")
(node 70 "Kam-YuenKwong")
(node 71 "I.P.Zois MathematicalInstitute")
(node 72 "Krzysztof")
(node 73 "HermannNicolai AEIPotsdam ")
(node 74 "ThomasThiemann")
(node 75 "JosephConlon Cambridge ")
(node 76 "H.Ochiai")
(node 77 "MirjamCveti\vc")
(node 78 "J.Phillips")
(node 79 "MariaRodriguez-Martinez IAP")
(node 80 "MohammadNouri-Zonoz")
(node 81 "Univ.ofFlorida ")
(node 82 "VasiliosZarikas")
(node 83 "AndrewChamblin MIT ")
(node 84 "V.M.Mostepanenko Joao")
(node 85 "N.A.Gromov")
(node 86 "B.Kleihaus UCD")
(node 87 "Beijing ")
(node 88 "Z.Lalak")
(node 89 "GernotAkemann")
(node 90 "Yi-YenWu JohnsHopkinsUniversity ")
(node 91 "DanielaBigatti")
(node 92 "IzabelaProchnicka")
(node 93 "R.Sauser")
(node 94 "TaichiroKugo")
(node 95 "A.I.Pashnev")
(node 96 "T.Nakatsu")
(node 97 "EdwardWitten")
(node 98 "JosephPolchinski")
(node 99 "CumrunVafa")
(node 100 "Bhubaneswar")
(node 101 "R.D.Tangerman")
(node 102 "JozsefGyurusi ResearchIns.forParticle")
(node 103 "LaszloFeher")
(node 104 "R.Shankar")
(node 105 "Yu.A.Sitenko BITP")
(node 106 "JuanPedroGarrahan")
(node 107 "ParArvidsson")
(node 108 "AlexeiKitaev")
(node 109 "G.Haak")
(node 110 "SamirK.Paul")
(node 111 "Warsaw")
)
(property  0 layout "viewLayout"
(default "(0,0,0)" "()")(node 0 "(0,0,0)")
(node 1 "(0,0,0)")
(node 2 "(0,0,0)")
(node 3 "(0,0,0)")
(node 4 "(0,0,0)")
(node 5 "(0,0,0)")
(node 6 "(0,0,0)")
(node 7 "(0,0,0)")
(node 8 "(375.0,5.5,0)")
(node 9 "(0,0,0)")
(node 10 "(0,0,0)")
(node 11 "(250.0,0.0,0)")
(node 12 "(0,0,0)")
(node 13 "(0,0,0)")
(node 14 "(0,0,0)")
(node 15 "(125.0,5.0,0)")
(node 16 "(0,0,0)")
(node 17 "(0,0,0)")
(node 18 "(0,0,0)")
(node 19 "(0,0,0)")
(node 20 "(125.0,4.0,0)")
(node 21 "(0,0,0)")
(node 22 "(0,0,0)")
(node 23 "(0,0,0)")
(node 24 "(250.0,0.0,0)")
(node 25 "(250.0,1.5,0)")
(node 26 "(0,0,0)")
(node 27 "(625.0,29.0,0)")
(node 28 "(125.0,0.0,0)")
(node 29 "(0,0,0)")
(node 30 "(875.0,280.5,0)")
(node 31 "(0,0,0)")
(node 32 "(375.0,5.0,0)")
(node 33 "(0,0,0)")
(node 34 "(0,0,0)")
(node 35 "(0,0,0)")
(node 36 "(875.0,36.5,0)")
(node 37 "(125.0,26.0,0)")
(node 38 "(0,0,0)")
(node 39 "(0,0,0)")
(node 40 "(0,0,0)")
(node 41 "(0,0,0)")
(node 42 "(0,0,0)")
(node 43 "(0,0,0)")
(node 44 "(0,0,0)")
(node 45 "(0,0,0)")
(node 46 "(0,0,0)")
(node 47 "(0,0,0)")
(node 48 "(0,0,0)")
(node 49 "(0,0,0)")
(node 50 "(0,0,0)")
(node 51 "(0,0,0)")
(node 52 "(0,0,0)")
(node 53 "(0,0,0)")
(node 54 "(0,0,0)")
(node 55 "(0,0,0)")
(node 56 "(0,0,0)")
(node 57 "(0,0,0)")
(node 58 "(0,0,0)")
(node 59 "(1250.0,99.5,0)")
(node 60 "(0,0,0)")
(node 61 "(0,0,0)")
(node 62 "(0,0,0)")
(node 63 "(0,0,0)")
(node 64 "(0,0,0)")
(node 65 "(0,0,0)")
(node 66 "(0,0,0)")
(node 67 "(125.0,97.0,0)")
(node 68 "(0,0,0)")
(node 69 "(0,0,0)")
(node 70 "(0,0,0)")
(node 71 "(0,0,0)")
(node 72 "(0,0,0)")
(node 73 "(0,0,0)")
(node 74 "(0,0,0)")
(node 75 "(0,0,0)")
(node 76 "(0,0,0)")
(node 77 "(0,0,0)")
(node 78 "(0,0,0)")
(node 79 "(0,0,0)")
(node 80 "(0,0,0)")
(node 81 "(0,0,0)")
(node 82 "(0,0,0)")
(node 83 "(0,0,0)")
(node 84 "(0,0,0)")
(node 85 "(0,0,0)")
(node 86 "(0,0,0)")
(node 87 "(0,0,0)")
(node 88 "(125.0,0.0,0)")
(node 89 "(0,0,0)")
(node 90 "(0,0,0)")
(node 91 "(0,0,0)")
(node 92 "(0,0,0)")
(node 93 "(0,0,0)")
(node 94 "(0,0,0)")
(node 95 "(0,0,0)")
(node 96 "(125.0,2.5,0)")
(node 97 "(875.0,257.0,0)")
(node 98 "(125.0,4.0,0)")
(node 99 "(250.0,44.5,0)")
(node 100 "(250.0,1.5,0)")
(node 101 "(125.0,0.0,0)")
(node 102 "(0,0,0)")
(node 103 "(0,0,0)")
(node 104 "(125.0,1.0,0)")
(node 105 "(0,0,0)")
(node 106 "(0,0,0)")
(node 107 "(0,0,0)")
(node 108 "(0,0,0)")
(node 109 "(0,0,0)")
(node 110 "(125.0,0.0,0)")
(node 111 "(0,0,0)")
)
(property  0 color "viewColor"
(default "(255,0,0,255)" "(0,0,0,255)")(node 0 "(250,184,0,255)")
(node 1 "(255,204,0,255)")
(node 2 "(230,104,0,255)")
(node 3 "(255,204,0,255)")
(node 4 "(255,204,0,255)")
(node 5 "(255,204,0,255)")
(node 6 "(255,204,0,255)")
(node 7 "(255,204,0,255)")
(node 8 "(255,204,0,255)")
(node 9 "(255,204,0,255)")
(node 10 "(255,204,0,255)")
(node 11 "(255,204,0,255)")
(node 12 "(255,204,0,255)")
(node 13 "(255,204,0,255)")
(node 14 "(255,204,0,255)")
(node 15 "(255,204,0,255)")
(node 16 "(255,204,0,255)")
(node 17 "(255,204,0,255)")
(node 18 "(255,204,0,255)")
(node 19 "(255,204,0,255)")
(node 20 "(255,204,0,255)")
(node 21 "(255,204,0,255)")
(node 22 "(255,204,0,255)")
(node 23 "(255,204,0,255)")
(node 24 "(255,204,0,255)")
(node 25 "(255,204,0,255)")
(node 26 "(255,204,0,255)")
(node 27 "(255,204,0,255)")
(node 28 "(255,204,0,255)")
(node 29 "(255,204,0,255)")
(node 30 "(245,164,0,255)")
(node 31 "(255,204,0,255)")
(node 32 "(255,204,0,255)")
(node 33 "(255,204,0,255)")
(node 34 "(255,204,0,255)")
(node 35 "(255,204,0,255)")
(node 36 "(255,204,0,255)")
(node 37 "(250,184,0,255)")
(node 38 "(255,204,0,255)")
(node 39 "(255,204,0,255)")
(node 40 "(255,204,0,255)")
(node 41 "(255,204,0,255)")
(node 42 "(255,204,0,255)")
(node 43 "(255,204,0,255)")
(node 44 "(255,204,0,255)")
(node 45 "(255,204,0,255)")
(node 46 "(255,204,0,255)")
(node 47 "(255,204,0,255)")
(node 48 "(255,204,0,255)")
(node 49 "(255,204,0,255)")
(node 50 "(255,204,0,255)")
(node 51 "(255,204,0,255)")
(node 52 "(255,204,0,255)")
(node 53 "(255,204,0,255)")
(node 54 "(255,204,0,255)")
(node 55 "(255,204,0,255)")
(node 56 "(255,204,0,255)")
(node 57 "(255,204,0,255)")
(node 58 "(255,204,0,255)")
(node 59 "(250,184,0,255)")
(node 60 "(255,204,0,255)")
(node 61 "(255,204,0,255)")
(node 62 "(255,204,0,255)")
(node 63 "(255,204,0,255)")
(node 64 "(255,204,0,255)")
(node 65 "(255,204,0,255)")
(node 66 "(255,204,0,255)")
(node 67 "(240,144,0,255)")
(node 68 "(255,204,0,255)")
(node 69 "(255,204,0,255)")
(node 70 "(255,204,0,255)")
(node 71 "(255,204,0,255)")
(node 72 "(255,204,0,255)")
(node 73 "(255,204,0,255)")
(node 74 "(255,204,0,255)")
(node 75 "(255,204,0,255)")
(node 76 "(255,204,0,255)")
(node 77 "(250,184,0,255)")
(node 78 "(255,204,0,255)")
(node 79 "(255,204,0,255)")
(node 80 "(255,204,0,255)")
(node 81 "(255,204,0,255)")
(node 82 "(255,204,0,255)")
(node 83 "(255,204,0,255)")
(node 84 "(255,204,0,255)")
(node 85 "(255,204,0,255)")
(node 86 "(255,204,0,255)")
(node 87 "(255,204,0,255)")
(node 88 "(255,204,0,255)")
(node 89 "(255,204,0,255)")
(node 90 "(255,204,0,255)")
(node 91 "(250,184,0,255)")
(node 92 "(255,204,0,255)")
(node 93 "(255,204,0,255)")
(node 94 "(255,204,0,255)")
(node 95 "(255,204,0,255)")
(node 96 "(255,204,0,255)")
(node 97 "(235,124,0,255)")
(node 98 "(240,144,0,255)")
(node 99 "(250,184,0,255)")
(node 100 "(255,204,0,255)")
(node 101 "(255,204,0,255)")
(node 102 "(255,204,0,255)")
(node 103 "(255,204,0,255)")
(node 104 "(255,204,0,255)")
(node 105 "(255,204,0,255)")
(node 106 "(255,204,0,255)")
(node 107 "(255,204,0,255)")
(node 108 "(255,204,0,255)")
(node 109 "(255,204,0,255)")
(node 110 "(255,204,0,255)")
(node 111 "(255,204,0,255)")
)
(property  0 size "viewSize"
(default "(40,40,5)" "(200,200,0)")
)
(property  0 int "viewFontSize"
(default "5" "5")
)
(property  0 int "viewShape"
(default "2" "0")
)
)
animation.py
# Powered by Python 2.7
 
# To cancel the modifications performed by the script
# on the current graph, click on the undo button.
 
# Some useful keyboards shortcuts : 
#   * Ctrl + D : comment selected lines.
#   * Ctrl + Shift + D  : uncomment selected lines.
#   * Ctrl + I : indent selected lines.
#   * Ctrl + Shift + I  : unindent selected lines.
#   * Ctrl + Return  : run script.
#   * Ctrl + F  : find selected text.
#   * Ctrl + R  : replace selected text.
#   * Ctrl + Space  : show auto-completion dialog.
 
from tulip import *
import time
import math
 
# the updateVisualization(centerViews = True) function can be called
# during script execution to update the opened views
 
# the pauseScript() function can be called to pause the script execution.
# To resume the script execution, you will have to click on the "Run script " button.
 
# the runGraphScript(scriptFile, graph) function can be called to launch another edited script on a tlp.Graph object.
# The scriptFile parameter defines the script name to call (in the form [a-zA-Z0-9_]+.py)
 
# the main(graph) function must be defined 
# to run the script on the current graph
 
def setPos(node,x,y):
	viewLayout =  graph.getLayoutProperty("viewLayout")
	viewLayout[node]=tlp.Coord(x,y,0)
#	updateVisualization(centerViews = True)
 
 
def main(graph): 
	viewBorderColor =  graph.getColorProperty("viewBorderColor")
	viewBorderWidth =  graph.getDoubleProperty("viewBorderWidth")
	viewColor =  graph.getColorProperty("viewColor")
	viewFont =  graph.getStringProperty("viewFont")
	viewFontSize =  graph.getIntegerProperty("viewFontSize")
	viewLabel =  graph.getStringProperty("viewLabel")
	viewLabelColor =  graph.getColorProperty("viewLabelColor")
	viewLabelPosition =  graph.getIntegerProperty("viewLabelPosition")
	viewLabelRotation =  graph.getDoubleProperty("viewLabelRotation")
	viewLayout =  graph.getLayoutProperty("viewLayout")
	viewMetaGraph =  graph.getGraphProperty("viewMetaGraph")
	viewMetric =  graph.getDoubleProperty("viewMetric")
	viewRotation =  graph.getDoubleProperty("viewRotation")
	viewSelection =  graph.getBooleanProperty("viewSelection")
	viewShape =  graph.getIntegerProperty("viewShape")
	viewSize =  graph.getSizeProperty("viewSize")
	viewSrcAnchorShape =  graph.getIntegerProperty("viewSrcAnchorShape")
	viewSrcAnchorSize =  graph.getSizeProperty("viewSrcAnchorSize")
	viewTexture =  graph.getStringProperty("viewTexture")
	viewTgtAnchorShape =  graph.getIntegerProperty("viewTgtAnchorShape")
	viewTgtAnchorSize =  graph.getSizeProperty("viewTgtAnchorSize")
 
 
	for n in graph.getNodes():
		if viewLabel[n]=="H.Lu":
			viewLabelColor[n]=tlp.Color(255,51,51)
 
	anneenode=graph.addNode()
	viewLayout[anneenode]=tlp.Coord(1000,-500,0)
	viewLabelPosition[anneenode]=1
	viewColor[anneenode]=tlp.Color(0,0,0,0)
	viewSize[anneenode]=tlp.Size(1,500,0)
	viewLabelColor[anneenode]=tlp.Color(255,51,51)
	viewLabel[anneenode]="1993"
 
	centre=graph.addNode()
	viewSize[centre]=tlp.Size(0,0,0)
	viewLayout[centre]=tlp.Coord(-50,-50,0)
	droite=graph.addNode()
	viewSize[droite]=tlp.Size(0,0,0)
	viewLayout[droite]=tlp.Coord(2500,-50,0)
	haut=graph.addNode()
	viewSize[haut]=tlp.Size(0,0,0)
	viewLayout[haut]=tlp.Coord(-50,2000,0)
 
	abs=graph.addEdge(centre,droite)
	ord=graph.addEdge(centre,haut)
	viewLabel[abs]="Nombe de publication"
 
 
	for i in range(10):
 
		etapes=30.0	
 
		f=open("/net/cremi/lmarmies/espaces/travail/visu/Projet/coord"+str(i+1994),"r")
		coord=[]
		for ligne in f:
			coord.append(ligne.split())
 
		cpt=0
		nextPosX={}#dico avec cle : noeud et valeur : ses prochaine position
		nextPosY={}#dico avec cle : noeud et valeur : ses prochaine position
		for n in graph.getNodes():
			if viewLayout[n][1]>=0 and viewLayout[n][0]>=0:
				nextPosX[n]=[]
				nextPosY[n]=[]
 
				x=viewLayout[n][0]
				y=viewLayout[n][1]
				newX=float(coord[cpt][0])
				newY=float(coord[cpt][1])
 
				differenceX = math.fabs(x-newX)
				differenceY = math.fabs(y-newY)
				etapeX=differenceX/etapes
				etapeY=differenceY/etapes
 
				if x>newX:
					for i in range(int(etapes)):
						x-=etapeX
						nextPosX[n].append(x)
				else:		
					for i in range(int(etapes)):
						x+=etapeX
						nextPosX[n].append(x)
 
				if y>newY:
					for i in range(int(etapes)):
						y-=etapeY
						nextPosY[n].append(y)
				else:		
					for i in range(int(etapes)):
						y+=etapeY
						nextPosY[n].append(y)
 
 
 
				cpt+=1
 
		cpt=0	
 
		for j in range(int(etapes)):
			for n in graph.getNodes():		
				if viewLayout[n][1]>=0 and viewLayout[n][0]>=0:			
					viewLayout[n]=tlp.Coord(nextPosX[n][j],nextPosY[n][j],0)
					time.sleep(0.001)
					cpt+=1
 
			updateVisualization(centerViews = True)
 
 
		viewLabel[anneenode]=str(int(viewLabel[anneenode])+1)
		cpt=0
		for n in graph.getNodes():
			if viewLayout[n][1]>=0 and viewLayout[n][0]>=0:
				viewLayout[n]=tlp.Coord(float(coord[cpt][0]),float(coord[cpt][1]),0)
				cpt+=1
 
 
		time.sleep(3)
genereCoord.py
import os
from random import choice
 
dicoAuteursTotal={}#contient en clef l'auteur, et en valeur un tableau avec en 0 : nb de publi en 1 le nb de ref vers lui
 
dicoPubli={}#cle : artcile, valeur : liste des artciles qui le citent
dicoCoord={}#cle : auteur, valeur : tableau de coord par annee
 
def toTlp(dicoAuteurs,dicoCoord,out,rapportmax):
	f = open (out,"w")
 
	f.write("(tlp \"2.3\"\n")
 
	f.write("(nb_nodes " + str(len(dicoCoord)) + ")\n");
	f.write("(nodes 0.." + str(len(dicoCoord) - 1) + ")\n");
	f.write("(nb_edges 0)\n");
 
	#on ecrit le label
	f.write("(property  0 string \"viewLabel\"\n");
	f.write("(default \"\" \"\")\n");
 
	cpt=0
	for author in dicoCoord:
		f.write("(node "+str(cpt)+" \""+author.replace("("," ").replace(")"," ").replace("&"," ").replace(";"," ").replace("\"","")+"\")\n")
		cpt+=1
 
	f.write(")\n")
 
 
 
	#on met les coordonnees
	f.write("(property  0 layout \"viewLayout\"\n");
	f.write("(default \"(0,0,0)\" \"()\")");
 
	cpt=0
	for author in dicoCoord:
		f.write("(node "+str(cpt)+" \"("+str(dicoCoord[author][0][0])+","+str(dicoCoord[author][0][1])+",0)\")\n")
		cpt+=1
 
	f.write(")\n")
 
 
 
	dicoCouleurs={}
	dicoCouleurs[0]=[255,204,0]
	i=1
	while i<10:
		dicoCouleurs[i]=[dicoCouleurs[i-1][0]-5,dicoCouleurs[i-1][1]-20,dicoCouleurs[i-1][2]]
 
		i+=1
 
	#on change les couleurs
	f.write("(property  0 color \"viewColor\"\n");
	f.write("(default \"(255,0,0,255)\" \"(0,0,0,255)\")");
 
	cpt=0
	for author in dicoCoord:
 
		rapport=dicoAuteurs[author][2]/float(rapportmax)*10.0
 
 
		if rapport==10.0:
			rapport=9.0
		bonIndice=int(rapport)
 
		f.write("(node "+str(cpt)+" \"("+str(dicoCouleurs[bonIndice][0])+","+str(dicoCouleurs[bonIndice][1])+","+str(dicoCouleurs[bonIndice][2])+",255)\")\n")
 
 
		cpt+=1
 
	f.write(")\n")
 
 
	#on change la taille
	f.write("(property  0 size \"viewSize\"\n");
	f.write("(default \"(40,40,5)\" \"(200,200,0)\")\n");
	f.write(")\n")
 
 
	f.write("(property  0 int \"viewFontSize\"\n");
	f.write("(default \"5\" \"5\")\n");
	f.write(")\n")
 
	#on change la forme
	f.write("(property  0 int \"viewShape\"\n");
	f.write("(default \"2\" \"0\")\n");
	f.write(")\n")
 
	f.write(")")
	f.close()
 
 
 
 
f=open('data/Cit-HepTh.txt','r')
 
print 1
 
for ligne in f:
	if not "#" in ligne:
 
		if not dicoPubli.has_key(ligne.split()[0]):
			dicoPubli[ligne.split()[0]]=[]
		if not dicoPubli.has_key(ligne.split()[1]):
			dicoPubli[ligne.split()[1]]=[]
 
		dicoPubli[ligne.split()[1]].append(ligne.split()[0])
 
 
f.close()	
 
print 2
 
#~ print dicoPubli
 
annee=1993
 
while (annee<2004):
 
	dicoAuteurs={}#contient en clef l'auteur, et en valeur un tableau avec en 0 : nb de publi en 1 le nb de ref vers lui
 
	listeFichiers=os.listdir("data/"+str(annee))
 
	for fichier in listeFichiers:			
 
		f=open('data/'+str(annee)+"/"+fichier,'r')			
 
		article=fichier.replace(".abs","")		
 
		while article[0]=="0":
			article=article[1:]
 
		#si l'article n'etait pas dans la liste on l'ajoute
		if not dicoPubli.has_key(article):
			dicoPubli[article]=[]
 
 
		autheurs=[]	
 
		for ligne in f:
			if ("Authors:" in ligne) or ("Author:" in ligne):
				autheurs=ligne.split(":")[1].replace(" and ",",").replace("\n","").replace(" ","").split(",")
 
 
		#on parcourt les auteurs
 
		for autheur in autheurs:
 
			if autheur!="":	
 
 
 
 
				if not dicoAuteurs.has_key(autheur):
					dicoAuteurs[autheur]=[0,0,0]
 
				dicoAuteurs[autheur]=[dicoAuteurs[autheur][0]+1,dicoAuteurs[autheur][1],0]
 
				for art in dicoPubli[article]:
					dicoAuteurs[autheur]=[dicoAuteurs[autheur][0],dicoAuteurs[autheur][1]+1,0]
 
	for autheur in dicoAuteurs:
		dicoAuteurs[autheur][2]=float(float(dicoAuteurs[autheur][1])/float(dicoAuteurs[autheur][0]))
 
 
	publimax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][0]>publimax:
			publimax=dicoAuteurs[a][0]
			autheurMax=a
 
	print autheurMax,publimax
 
 
	refmax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][1]>refmax:
			refmax=dicoAuteurs[a][1]
			autheurMax=a
 
	print autheurMax,refmax
 
	rapportmax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][2]>rapportmax:
			rapportmax=dicoAuteurs[a][2]
			autheurMax=a
 
	print autheurMax,rapportmax
 
	print 3	
 
 
 
	for auteur in dicoAuteurs:
 
 
		if not dicoCoord.has_key(auteur):
			dicoCoord[auteur]=[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]]
 
		dicoCoord[auteur][annee-1993]=[(dicoAuteurs[auteur][0]/120.0)*15000,dicoAuteurs[auteur][1]* 0.5]
 
 
 
		if not dicoAuteursTotal.has_key(auteur):
			dicoAuteursTotal[auteur]=[0,0,0]
		dicoAuteursTotal[auteur]=[dicoAuteursTotal[auteur][0]+dicoAuteurs[auteur][0],dicoAuteursTotal[auteur][1]+dicoAuteurs[auteur][1],0]
 
	print annee
	annee+=1
 
 
for autheur in dicoAuteursTotal:
	dicoAuteursTotal[autheur][2]=float(float(dicoAuteursTotal[autheur][1])/float(dicoAuteursTotal[autheur][0]))
 
 
publimax = 0
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][0]>publimax:
		publimax=dicoAuteursTotal[a][0]
		autheurMax=a
 
print autheurMax,publimax
 
refmax = 0
 
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][1]>refmax:
		refmax=dicoAuteursTotal[a][1]
		autheurMax=a
 
print autheurMax,refmax
 
rapportmax = 0
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][2]>rapportmax:
		rapportmax=dicoAuteursTotal[a][2]
		autheurMax=a
 
print autheurMax,rapportmax
 
print dicoCoord["EdwardWitten"]
 
dicoCoordPetit={}
listeAuteursComplet=[]
for a in dicoCoord:
	listeAuteursComplet.append(a)
 
 
listeAuteursPetit=["H.Lu","EdwardWitten","CumrunVafa","C.N.Pope","A.A.Tseytlin","Shin'ichiNojiri","AshokeSen","SergeiD.Odintsov","CumrunVafa","C.Vafa","N.Seiberg","JosephPolchinski","S.Ferrara"]
for auteur in listeAuteursPetit:
	dicoCoordPetit[auteur]=dicoCoord[auteur]
 
 
 
for i in range(100):
	auteur=choice(listeAuteursComplet)
	dicoCoordPetit[auteur]=dicoCoord[auteur]
 
 
 
toTlp(dicoAuteursTotal,dicoCoordPetit,"bouge.tlp",rapportmax)
 
#on genere les fichiers de coordonnees
for i in range(11):
	f=open("coord"+str(i+1993),"w")
	for auteur in dicoCoordPetit:
		f.write(str(dicoCoord[auteur][i][0])+" "+str(round(dicoCoord[auteur][i][1],3))+"\n")
communaute.py
import os
import copy
from random import choice
import random
 
dicoAuteursTotal={}#contient en clef l'auteur, et en valeur un tableau avec en 0 : nb de publi en 1 le nb de ref vers lui, 2 le rapport
 
dicoPubli={}#cle : artcile, valeur : liste des artciles qui le citent
 
dicoInfosAuteurs={}#contient en clef l'auteur, en 0 liste de ses artciles et en 1 la liste d'auteurs qui le citent 
dicoPubliAuteurs={}#contient en clef l'article et en valeur la liste des auteurs
 
 
 
def toTlp(dicoCoordPoints,dicoNbPubli,dicoCoord,communautes,out):
	f = open (out,"w")
 
	#~ rapportTotal=float(refmax/publimax)
#~ 
	#~ facteurMultiplicateur=65/rapportTotal
 
	f.write("(tlp \"2.3\"\n")
 
	nbNodes=0
	for a in dicoCoordPoints:
		for b in dicoCoordPoints[a]:
			nbNodes+=1
 
	f.write("(nb_nodes " + str(nbNodes+len(dicoCoordPoints)) + ")\n");
	f.write("(nodes 0.." + str(nbNodes+len(dicoCoordPoints) - 1) + ")\n");
	f.write("(nb_edges 0)\n");
 
	#on ecrit le label
	f.write("(property  0 string \"viewLabel\"\n");
	f.write("(default \"\" \"\")\n");
 
	cpt=0
	nbComm=0
	for comm in dicoCoordPoints:
		nbComm+=1
		f.write("(node "+str(cpt)+" \""+str(len(communautes[comm]))+"\")\n")
		cpt+=1
		for auteur in communautes[comm]:
 
			f.write("(node "+str(cpt)+" \""+auteur.replace("("," ").replace(")"," ").replace("&"," ").replace(";"," ").replace("\"","")+"\")\n")
			cpt+=1
 
	f.write(")\n")
 
 
 
	#on met les coordonnees
	f.write("(property  0 layout \"viewLayout\"\n");
	f.write("(default \"(0,0,0)\" \"()\")");
 
	cpt=0
	for comm in dicoCoordPoints:
		f.write("(node "+str(cpt)+" \"("+str(dicoCoord[comm][0])+","+str(dicoCoord[comm][1])+",0)\")\n")
		cpt+=1
		for point in dicoCoordPoints[comm]:
			f.write("(node "+str(cpt)+" \"("+str(point[0])+","+str(point[1])+",0)\")\n")
			cpt+=1
 
	f.write(")\n")
 
	#on change les couleurs
 
 
	f.write("(property  0 color \"viewColor\"\n");
	f.write("(default \"(255,255,255,255)\" \"(0,0,0,255)\")\n");
 
	cpt=0
	for comm in dicoCoordPoints:
 
		r=random.random()*255
		g=random.random()*255
		b=random.random()*255
 
		f.write("(node "+str(cpt)+" \"("+str(int(r))+","+str(int(g))+","+str(int(b))+",100)\")\n")
		cpt+=1
 
 
		for point in dicoCoordPoints[comm]:
 
			f.write("(node "+str(cpt)+" \"("+str(int(r))+","+str(int(g))+","+str(int(b))+",255)\")\n")
			cpt+=1
 
	f.write(")\n")
 
 
	#on change la taille
	f.write("(property  0 size \"viewSize\"\n");
	f.write("(default \"("+str(5)+","+str(5)+",5)\" \"(200,200,0)\")\n");
 
	cpt=0
	for comm in dicoCoordPoints:
		f.write("(node "+str(cpt)+" \"("+str(dicoNbPubli[comm]+5)+","+str(dicoNbPubli[comm]+5)+",0)\")\n")
		cpt+=1
		for point in dicoCoordPoints[comm]:
			cpt+=1
 
 
 
	f.write(")\n")
 
	#on change la forme
	f.write("(property  0 int \"viewShape\"\n");
	f.write("(default \"2\" \"0\")\n");
	f.write(")\n")
 
 
	f.write(")\n")
	f.close()
 
 
f=open('data/Cit-HepTh.txt','r')
 
print 1
 
for ligne in f:
	if not "#" in ligne:
 
		if not dicoPubli.has_key(ligne.split()[0]):
			dicoPubli[ligne.split()[0]]=[]
		if not dicoPubli.has_key(ligne.split()[1]):
			dicoPubli[ligne.split()[1]]=[]
 
		dicoPubli[ligne.split()[1]].append(ligne.split()[0])
 
 
f.close()	
 
print 2
 
annee=1992
 
while (annee<2004):
 
	dicoAuteurs={}#contient en clef l'auteur, et en valeur un tableau avec en 0 : nb de publi en 1 le nb de ref vers lui
 
	listeFichiers=os.listdir("data/"+str(annee))
 
	for fichier in listeFichiers:			
 
		f=open('data/'+str(annee)+"/"+fichier,'r')			
 
		article=fichier.replace(".abs","")		
 
		while article[0]=="0":
			article=article[1:]
 
		#si l'article n'etait pas dans la liste on l'ajoute
		if not dicoPubli.has_key(article):
			dicoPubli[article]=[]
 
		#si l'article n'etait pas dans la liste on l'ajoute
		if not dicoPubliAuteurs.has_key(article):
			dicoPubliAuteurs[article]=[]
 
		auteurs=[]	
 
		for ligne in f:
			if ("Authors:" in ligne) or ("Author:" in ligne):
				auteurs=ligne.split(":")[1].replace(" and ",",").replace("\n","").replace(" ","").split(",")
 
 
		#on parcourt les auteurs
 
		for auteur in auteurs:
 
			if auteur!="":	
 
				dicoPubliAuteurs[article].append(auteur)
 
				if not dicoAuteurs.has_key(auteur):
					dicoAuteurs[auteur]=[0,0,0]
 
				if not dicoInfosAuteurs.has_key(auteur):
					dicoInfosAuteurs[auteur]=[[],[]]
 
 
				dicoInfosAuteurs[auteur][0].append(article)	
 
				dicoAuteurs[auteur]=[dicoAuteurs[auteur][0]+1,dicoAuteurs[auteur][1],0]
 
				for art in dicoPubli[article]:
					dicoAuteurs[auteur]=[dicoAuteurs[auteur][0],dicoAuteurs[auteur][1]+1,0]
 
 
	for autheur in dicoAuteurs:
		dicoAuteurs[autheur][2]=float(float(dicoAuteurs[autheur][1])/float(dicoAuteurs[autheur][0]))
 
 
	publimax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][0]>publimax:
			publimax=dicoAuteurs[a][0]
			autheurMax=a
 
	refmax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][1]>refmax:
			refmax=dicoAuteurs[a][1]
			autheurMax=a
 
 
	rapportmax = 0
	autheurMax=""
	for a in dicoAuteurs:
 
		if dicoAuteurs[a][2]>rapportmax:
			rapportmax=dicoAuteurs[a][2]
			autheurMax=a
 
 
	print 3
 
 
	print annee	
	annee+=1
 
	for auteur in dicoAuteurs:
		if not dicoAuteursTotal.has_key(auteur):
			dicoAuteursTotal[auteur]=[0,0,0]
		dicoAuteursTotal[auteur]=[dicoAuteursTotal[auteur][0]+dicoAuteurs[auteur][0],dicoAuteursTotal[auteur][1]+dicoAuteurs[auteur][1],0]
 
 
 
for autheur in dicoAuteursTotal:
	dicoAuteursTotal[autheur][2]=float(float(dicoAuteursTotal[autheur][1])/float(dicoAuteursTotal[autheur][0]))
 
 
publimax = 0
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][0]>publimax:
		publimax=dicoAuteursTotal[a][0]
		autheurMax=a
 
 
refmax = 0
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][1]>refmax:
		refmax=dicoAuteursTotal[a][1]
		autheurMax=a
 
 
rapportmax = 0
autheurMax=""
for a in dicoAuteursTotal:
 
	if dicoAuteursTotal[a][2]>rapportmax:
		rapportmax=dicoAuteursTotal[a][2]
		autheurMax=a
 
 
for auteur in dicoInfosAuteurs:
	listeCiteurs=[]
	listeArticlesCiteurs=[]
	for article in dicoInfosAuteurs[auteur][0]:
		for a in dicoPubli[article]:
			listeArticlesCiteurs.append(a)
 
 
	for article in listeArticlesCiteurs:
		for auteurCiteur in dicoPubliAuteurs[article]:
			if not auteurCiteur in listeCiteurs:
				#~ if not auteur in dicoInfosAuteurs[auteurCiteur][1]:
				listeCiteurs.append(auteurCiteur)
 
 
 
 
 
 
 
	dicoInfosAuteurs[auteur][1]=listeCiteurs
 
 
communautes=[]
 
 
auteursRestants=[]
for auteur in dicoInfosAuteurs:
	auteursRestants.append(auteur)
 
 
for auteur in dicoInfosAuteurs:
	if auteur in auteursRestants:
		proches=[]
		for citeur in dicoInfosAuteurs[auteur][1]:
			if (citeur in auteursRestants) and citeur!=auteur:
				for citeur2 in dicoInfosAuteurs[citeur][1]:
					if citeur2==auteur:
						proches.append(citeur)
						break
 
		comm=[auteur]
		auteursRestants.remove(auteur)
		for p in proches:
			comm.append(p)
			auteursRestants.remove(p)
 
		if len(comm)>3:			 
			communautes.append(comm)
 
 
print communautes
print len(communautes)
 
nbA=[]
for c in communautes:
	for a in c:
		if not a in nbA:
			nbA.append(a)
 
print len(nbA)
 
 
dicoNbPubli={}#cle : communaute, valeur nb de publi 
dicoCoord={}#cle : communaute, valeur coordonnees
 
 
nbPubliMax=0
for i in range(25):
	comm=choice(communautes)
 
	nbPubli=0
	for auteur in comm:
		nbPubli+=dicoAuteursTotal[auteur][0]
 
	if nbPubli>nbPubliMax:
		nbPubliMax=nbPubli	
 
	dicoNbPubli[communautes.index(comm)]=nbPubli
 
x=0
y=0
 
nbPixelColonne=0
 
listComm=[]
for comm in dicoNbPubli:
	listComm.append(comm)
 
dicoCoord[listComm[0]]=[x,y]
 
for i in range(len(listComm)):
	if i!=0:
		decalageY=(dicoNbPubli[listComm[i-1]]/2)+(dicoNbPubli[listComm[i]]/2)+10
 
		y-=decalageY
 
		avant=nbPixelColonne/500
		nbPixelColonne+=decalageY
		apres=nbPixelColonne/500
 
		if apres>avant:
			y=0
 
		dicoCoord[listComm[i]]=[(nbPixelColonne/500)*nbPubliMax,y]
 
 
print dicoCoord
 
dicoCoordPoints={}#cle : comm , valeur listre de coordonnees
 
for comm in listComm:
 
	dicoCoordPoints[comm]=[]
 
	for a in communautes[comm]:
		x=random.random()*dicoNbPubli[comm]/2
		y=random.random()*dicoNbPubli[comm]/2
		while (x+y>dicoNbPubli[comm]/2):
			x=random.random()*dicoNbPubli[comm]/2
			y=random.random()*dicoNbPubli[comm]/2
 
		if random.random()<0.5:
			x=-x
 
		if random.random()<0.5:
			y=-y		
 
 
		dicoCoordPoints[comm].append([x+dicoCoord[comm][0],y+dicoCoord[comm][1]])
 
 
 
toTlp(dicoCoordPoints,dicoNbPubli,dicoCoord,communautes,"testCommunautes.tlp")
tagCloud.py
# -*- coding: utf-8 -*-
from pytagcloud import create_tag_image, create_html_data, make_tags, \
    LAYOUT_HORIZONTAL, LAYOUTS
from pytagcloud.colors import COLOR_SCHEMES
from pytagcloud.lang.counter import get_tag_counts
from string import Template
import os
import time
import unittest
 
class Test(unittest.TestCase):
    """
    Generate tag clouds and save them to <YOURHOME>/pytagclouds/
    Note: All tests are disabled ('_' prefixed) by default
    """
 
    def setUp(self):
        self.test_output = os.path.join(os.getcwd(), 'out')
        self.hound = open(os.path.join(os.getcwd(), '1994TagsTitles.txt'), 'r')
 
        if not os.path.exists(self.test_output):
            os.mkdir(self.test_output )            
 
    def tearDown(self):
        self.hound.close()
 
    def test_tag_counter(self):
        tag_list = get_tag_counts(self.hound.read())[:50]
        print tag_list   
        self.assertTrue(('theory', 350) in tag_list)
 
    def test_make_tags(self):
        mtags = make_tags(get_tag_counts(self.hound.read())[:60])
        found = False
        for tag in mtags:
            if tag['tag'] == 'theory' and tag['size'] == 40:
                found = True
                break
 
        self.assertTrue(found)
 
    def test_layouts(self):
        start = time.time()
        tags = make_tags(get_tag_counts(self.hound.read())[:80], maxsize=120)
        for layout in LAYOUTS:
            create_tag_image(tags, os.path.join(self.test_output, 'cloud_%s.png' % layout),
                             size=(900, 600),
                             background=(255, 255, 255, 255),
                             layout=layout, fontname='Lobster')
        print "Duration: %d sec" % (time.time() - start)
 
    def test_large_tag_image(self):
        start = time.time()
        tags = make_tags(get_tag_counts(self.hound.read())[:80], maxsize=120, 
                         colors=COLOR_SCHEMES['audacity'])
        create_tag_image(tags, os.path.join(self.test_output, 'cloud_large.png'), 
                         size=(900, 600), background=(255, 255, 255, 255), 
                         layout=LAYOUT_HORIZONTAL, fontname='Lobster')
        print "Duration: %d sec" % (time.time() - start)
 
    def test_create_html_data(self):
        """
        HTML code sample
        """
        tags = make_tags(get_tag_counts(self.hound.read())[:100], maxsize=120, colors=COLOR_SCHEMES['audacity'])
        data = create_html_data(tags, (440,600), layout=LAYOUT_HORIZONTAL, fontname='PT Sans Regular')
 
        template_file = open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'web/template.html'), 'r')    
        html_template = Template(template_file.read())
 
        context = {}
 
        tags_template = '<li class="cnt" style="top: %(top)dpx; left: %(left)dpx; height: %(height)dpx;"><a class="tag %(cls)s" href="#%(tag)s" style="top: %(top)dpx;\
        left: %(left)dpx; font-size: %(size)dpx; height: %(height)dpx; line-height:%(lh)dpx;">%(tag)s</a></li>'
 
        context['tags'] = ''.join([tags_template % link for link in data['links']])
        context['width'] = data['size'][0]
        context['height'] = data['size'][1]
        context['css'] = "".join("a.%(cname)s{color:%(normal)s;}\
        a.%(cname)s:hover{color:%(hover)s;}" % 
                                  {'cname':k,
                                   'normal': v[0],
                                   'hover': v[1]} 
                                 for k,v in data['css'].items())
 
        html_text = html_template.substitute(context)
 
        html_file = open(os.path.join(self.test_output, 'cloud.html'), 'w')
        html_file.write(html_text)
        html_file.close()       
 
if __name__ == "__main__":
    unittest.main()
/net/html/perso/melancon/Visual_Analytics_Course/data/pages/alelievre_cdjemiel_lmarmiesse/aurelie_lelievre_christophe_djemiel_lucas_marmiesse.txt · Last modified: 2013/01/11 14:59 by cdjemiel