2013-05-10 14 views
9

Często spotykałem się i tworzyłem długoterminowe rozkłady/histogramy ze złożonych sieci, jak na poniższych rysunkach. Robią ciężki koniec tych ogonów, dobrze, bardzo ciężkie i zatłoczone z wielu obserwacji:Plotowanie log-binnedowych rozkładów stopni sieciowych

Classic long-tailed degree distribution

Jednak wiele czytałem publikacje mają znacznie czystsze rozkładów stopnia, że ​​nie ma tego clumpiness na koniec rozkład i obserwacje są bardziej równomiernie rozmieszczone.

! Classic long-tailed degree distribution

Jak utworzyć taki wykres za pomocą NetworkX i matplotlib?

+0

Co to jest dokładnie tutaj? Wygląda na to, że już osiągnąłeś rezultat, którego szukasz. Musisz być bardziej konkretny niż "lepiej". – Hooked

+2

Nie ma wątpliwości, tylko dzielę się tym, jak rozwiązałem problem i otwieram go na opinie innych, jeśli przeoczyłem coś w moim podejściu. –

+0

Lepszy sposób na zrobienie tego, w przeciwnym razie zostanie zamknięty, jest rozbicie go na pytanie i samodzielne udzielenie odpowiedzi. Zobacz http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ – Hooked

Odpowiedz

11

Użyj log binning (see also). Oto kod do pobrania obiektu Counter reprezentującego histogram wartości stopni i log-bin rozkładu w celu uzyskania sparser i gładszej dystrybucji.

import numpy as np 
def drop_zeros(a_list): 
    return [i for i in a_list if i>0] 

def log_binning(counter_dict,bin_count=35): 

    max_x = log10(max(counter_dict.keys())) 
    max_y = log10(max(counter_dict.values())) 
    max_base = max([max_x,max_y]) 

    min_x = log10(min(drop_zeros(counter_dict.keys()))) 

    bins = np.logspace(min_x,max_base,num=bin_count) 

    # Based off of: http://stackoverflow.com/questions/6163334/binning-data-in-python-with-scipy-numpy 
    bin_means_y = (np.histogram(counter_dict.keys(),bins,weights=counter_dict.values())[0]/np.histogram(counter_dict.keys(),bins)[0]) 
    bin_means_x = (np.histogram(counter_dict.keys(),bins,weights=counter_dict.keys())[0]/np.histogram(counter_dict.keys(),bins)[0]) 

    return bin_means_x,bin_means_y 

Generowanie klasyczną sieć bezskalowa w NetworkX a następnie wykreślenie tego:

import networkx as nx 
ba_g = nx.barabasi_albert_graph(10000,2) 
ba_c = nx.degree_centrality(ba_g) 
# To convert normalized degrees to raw degrees 
#ba_c = {k:int(v*(len(ba_g)-1)) for k,v in ba_c.iteritems()} 
ba_c2 = dict(Counter(ba_c.values())) 

ba_x,ba_y = log_binning(ba_c2,50) 

plt.xscale('log') 
plt.yscale('log') 
plt.scatter(ba_x,ba_y,c='r',marker='s',s=50) 
plt.scatter(ba_c2.keys(),ba_c2.values(),c='b',marker='x') 
plt.xlim((1e-4,1e-1)) 
plt.ylim((.9,1e4)) 
plt.xlabel('Connections (normalized)') 
plt.ylabel('Frequency') 
plt.show() 

Produkuje następujący wykres pokazujący zakładki pomiędzy „raw” dystrybucji na niebiesko i „binned” dystrybucji czerwony.

Comparison between raw and log-binned

Myśli o tym, jak poprawić to podejście lub zwrotne jeżeli Tęskniłam za coś oczywistego są mile widziane.

+0

pamiętaj, aby zaakceptować własną odpowiedź, jeśli jesteś z niej zadowolony! – tacaswell

+0

dla noobów, jakie są tutaj etykiety x-y? – sAguinaga

+0

Etykiety x-y to: oś x -> dziennik stopni napotkanych w sieci; oś y -> dziennik częstotliwości tych stopni. – FaCoffee

Powiązane problemy