Projekt Licencjacki- VisNetwork

Wprowadzenie

Tematem projektu licencjackiego jest przedstawienie możliwości pakietu visNetwork w języku programowania R. Pakiet ten jest szczególnie przydatny do wizualizacji zagadnień związanych z teorią grafów oraz bazami danych..

Zdecydowano, że zagadnienie zostanie zaprezentowane w formie poradnika w środowisku R Markdown zawierającego zarówno kod źródłowy, jak i jego wyniki w formie interaktywnych grafów. Praca została także wzbogacona o przykłady i komentarze, co znacząco ułatwia wykonywanie i analizę poszczególnych linijek kodu pakietu vis network czytelnikowi.

Funkcje

‘visNetwork’ jest pakietem języka R który służy do wizualizacji sieci, używając biblioteki ‘vis.js’ języka javascript.
  • Bazuje na ‘htmlwidgets’ więc jest kompatybilny z ‘shiny’, ‘R Markdown documents’ i ‘RStudio viewer’.
  • Pakiet posiada wszystkie funkcje dostępne w ‘vis.js’ API oraz kilka specjalnych funkcji R:
    • Łatwy w użyciu
    • Personalizacja kształtu, stylu, kolorów, rozmiaru
    • Działa na każdej współczesnej przeglądarce, nawet z kilkoma tysiącami węzłów
    • Interaktywność (podświetlenie, zwijanie i rozwijanie węzłów, przybliżanie i oddalanie, fizyka obiektów, ruch węzłów, spersonalizowane eventy)

Pojawiło się dużo nazw pakietów, żeby się nie pogubić jedno zdanie o każdym: ‘visNetwork’ = Nasz pakiet do wizualizacji i robienia wykresów ‘vis.js’ = to jest biblioteka javascript która odpowiada za wyświetlanie tych wszystkich rzeczy w przeglądarce, plus posiada w sobie kawałki bibliotek ‘DataSet’, ‘Timeline’, ‘Network’, ‘Graph2d’, ‘Graph3d’. ‘htmlwidgets’ = odpowiada za używanie javascript w konsoli R, prostymi słowami to jest to co pokazuje nam obrazki wykresów (i inne) w prawym dolnym rogu R ‘Shiny’ = Pakiet R który odpowiada za budowanie interaktywnych web-apps prosto w R. ‘R Markdown documents’ = file format for making dynamic documents with R ‘RStudio viewer’ = to jest po prostu nasz graficzny interfejs R (jak klikamy w dataset i mamy wizualnie tabelkę itd.)

W kodzie pojawia się mało znany operator >%> aka pipe-forward. Używa się go aby nie pisać funkcji w funkcji: plot_it(summarize_it(transform_it(clean_it(read_it(x))))) z użyciem >%> to spaghetti na górze wygląda: x %>% read_it %>% clean_it %>% transform_it %>% summarize_it %>% plot_it

Instalacja

Aby skorzystać z dodatkowych pakietów w R należy wykonać dwa kroki: 1.Zainstalować nowy pakiet.. Ten krok wystarczy wykonać raz, skopiuje on niezbędne pliki do katalogu z pakietami. 2.Włączyć zainstalowany pakiet w działającej sesji R. Ten krok należy wykonać po każdym uruchomieniu środowiska R. Spowoduje on, że w aktualnej sesji będzie można korzystać z funkcji i zbiorów danych dostępnych w pakiecie.

install.packages("visNetwork")
library(visNetwork)

Węzły

Możemy dostosować węzły wieloma opcjami na wiele różnych sposobów.

Indywidualna konfiguracja

Węzły ‘nodes’ muszą być ramką danych ‘data.frame’, z co najmniej jedną kolumną ‘id’. Węzeł konfigurujemy poprzez dodanie zmiennych do ‘data.frame’. Żeby zobaczyć wszystkie opcje można wywołać ‘?visNodes’.

Przykład zawierający najczęściej używane opcje:

nodes <- data.frame(id = 1:10,
# dodanie etykiety na węzeł
label = paste("Węzeł", 1:10),
# dodanie grup do węzełóW
group = c("GrA", "GrB"),
# przypisanie wielkości skalujących
value = 1:10,         
# ustalenie wyglądu każdego węzła
shape = c("square", "triangle", "box", "circle", "dot", "star",
          "ellipse", "database", "text", "diamond"),
# co ma sie wyświetlać gdy najedziemy na węzeł myszką
title = paste0("To jest węzeł numer ", 1:10),
# kolor
color = c("red", "magenta", "orange", "blue", "green"),
# cień
shadow = c(FALSE, TRUE, FALSE, TRUE, TRUE))
# stworzenie połączeń pomiędzy węzłami
edges <- data.frame(from = c(1,2,3,4,5,6), to = c(9,8,7,1,1,5))
# wizualizacja
visNetwork(nodes, edges, height = "500px", width = "100%")

Globalna konfiguracja

Jeżeli chcemy ustawić jakąś konfiguracje dla wszystkich węzłów, możemy to zrobić w prosty sposób używając wbudowanych funkcji ‘visNodes’ :

nodes <- data.frame(id = 1:6)
edges <- data.frame(from = c(1,1,1,1,1), to = c(2,3,4,5,6))

visNetwork(nodes, edges, width = "100%") %>%
  visNodes(shape = "circle",
           color = list(background = "lightblue",
                        border = "darkblue",
                        highlight = "yellow"),
           shadow = list(enabled = TRUE, size = 10)) %>%
  visLayout(randomSeed = 420)

Możemy łączyć ze sobą konfiguracje indywidualną i globalną:

nodes <- data.frame(id = 1:6,
                    shape = "square",
                    label = LETTERS[1:6])
edges <- data.frame(from = c(1,1,1,1,1), to = c(2,3,4,5,6))

visNetwork(nodes, edges, width = "100%") %>%
  visNodes(shape = "circle",
           color = list(background = "lightblue",
                        border = "darkblue",
                        highlight = "yellow"),
           shadow = list(enabled = TRUE, size = 10)) %>%
  visLayout(randomSeed = 420)

Używaj złożonej konfiguracji indywidualnie!

Gdy opcje są dostępne przy użyciu listy, możemy użyć ich w ramce danych z określoną notacją:

nodes <- data.frame(id = 1:4, 
                    color.background = c("red", "blue", "green", "pink"),
                    color.highlight.background = c("yellow", NA, "cyan", "magenta"), 
                    shadow.size = c(5, 10, 15, 20))

edges <- data.frame(from = c(1,2), to = c(2,4),
                    label = LETTERS[1:4], 
                    font.color =c ("red", "blue", "green", "pink"), 
                    font.size = c(10,20,30,40))

visNetwork(nodes, edges)

Krawędzie

Możemy dostosować krawędzie wieloma opcjami na wiele różnych sposobów, w taki sam sposób jak węzły.

Indywidualna konfiguracja

Krawędzie ‘edges’ muszą być ramką danych ‘data.frame’, z co najmniej jedną kolumną ‘from’ i ‘to’’. Węzeł konfigurujemy poprzez dodanie zmiennych do ‘data.frame’. Żeby zobaczyć wszystkie opcje można wywołać ‘?visNodes’.

Najczęściej używane są przedstawione w poniższym przykładzie:

edges <- data.frame(from = sample(1:10,8), 
                    to = sample(1:10, 8),
                    label = paste("Edge", 1:8),
                    length = c(100,500),
                    width = c(4,1),
                    arrows = c("to", "from", "middle", "middle;to"),
                    dashes = c(TRUE, FALSE),
                    title = paste("Edge", 1:8),
                    smooth = c(FALSE, TRUE),
                    shadow = c(FALSE, TRUE, FALSE, TRUE)) 

nodes <- data.frame(id = 1:10, 
                    group = c("A", "B"))

visNetwork(nodes, edges, height = "569px", width = "100%")

Globalna konfiguracja

Jeżeli chcemy ustawić jakąś konfiguracje dla wszystkich krawędzi, możemy to zrobić w prosty sposób używając wbudowanych funkcji ‘visEdges’ :

nodes <- data.frame(id = 1:9)
edges <- data.frame(from = c(2,4,3,5,7,6,9,2,8), to = c(1,2,4,3,6,5,7,8,9))

visNetwork(nodes, edges, width = "100%") %>%
  visEdges(shadow = TRUE,
           arrows = list(to = list(enabled = TRUE, scaleFactor = 2)),
           color = list(color = "green", highlight = "pink")) %>%
  visLayout(randomSeed = 12)

Możemy łączyć ze sobą konfiguracje indywidualną i globalną

nodes <- data.frame(id = 1:4, label = 1:4)
edges <- data.frame(from = c(2,4,3,2), 
                    to = c(1,2,4,3), 
                    dashes = c(TRUE, FALSE))

visNetwork(nodes, edges, width = "100%") %>% 
  visEdges(shadow = TRUE,
           arrows =list(to = list(enabled = TRUE, scaleFactor = 2)),
           color = list(color = "lightblue", highlight = "red")) %>%
  visLayout(randomSeed = 12)

Gdy opcje są dostępne przy użyciu listy, możemy użyć ich w ramce danych z określoną notacją:

visNetwork(nodes, edges, height = "500px", width = "100%")
nodes <- data.frame(id = 1:3, 
                    color.background = c("red", "blue", "green"),
                    color.highlight.background = c("red", NA, "red"), 
                    shadow.size = c(5, 15, 25))

edges <- data.frame(from = c(1,2), to = c(1,3),
                    label = LETTERS[1:2], 
                    font.color =c ("pink", "black"), 
                    font.size = c(10,20))

visNetwork(nodes, edges)  

Grupy

Możesz oddziaływać na grupę do węzła używając kolumny ‘group’ w węźle data.frame, i dodać konfiguracje dla grupy używając ‘visGroups’.

nodes <- data.frame(id = 1:5, group = c(rep("A", 2), rep("B", 3)))
edges <- data.frame(from = c(1,2,3,4,5), to = c(2,3,1,1,1))

visNetwork(nodes, edges, width = "100%") %>% 
  # grupa A kwadraty koloru cyan
  visGroups(groupname = "A", color = "cyan", shape = "square") %>% 
  # grupa B trojkaty koloru rozowego
  visGroups(groupname = "B", color = "pink", shape = "triangle")  

Legenda i tytul

Możesz dodać tytuł (‘main’), podtytuł (‘subtitle’) oraz stopkę (‘footer’) do swojej sieci:

nodes <- data.frame(id = 1:5)
edges <- data.frame(from = c(1,2), to = c(2,3))

visNetwork(nodes, edges, 
           main = list(text = "Tutaj jest tytuł", 
                       style = "font-family:Comic Sans MS;color:#ff0000;font-size:15px;text-align:center;"), 
           submain = list(text = "Tutaj jest podtytuł",
                          style = "color:#ff0000;text-align:center;"), 
           footer = list(text = "Tutaj jest stopka",
                          style = "color:#ff0000;text-align:center;"),
           width = "100%")

Używaj obrazów lub ikon

Obrazy

Aby użyć obrazów w węzłach, najpierw musisz ustawić shape w image lub circularImage. Następnie ustaw ścieżkę względną lub bezwzględną na wartości image W przypadku błędnej ścieżki dostępna jest opcja: brokenImage Możesz używać obramowań z shapeProperties i useBorderWithImage

path_to_images <- "https://raw.githubusercontent.com/datastorm-open/datastorm-open.github.io/master/visNetwork/data/img/indonesia/"

nodes <- data.frame(id = 1:4, 
                    shape = c("image", "circularImage"),
                    image = paste0(path_to_images, 1:4, ".png"),
                    label = "I'm an image")

edges <- data.frame(from = c(1,4,3,2), to = c(1,2,4,2))

visNetwork(nodes, edges, width = "100%") %>% 
  visNodes(shapeProperties = list(useBorderWithImage = TRUE)) %>%
  visLayout(randomSeed = 2)

fontAwesome icons

visNetwork obsługuje ikony fontAwesome. Font-awesome nie jest częścią domyślnych zależności, ale w razie potrzeby możesz użyć addFontAwesome().

Aby używać ikon w węzłach, musisz najpierw ustawić kształt na ikonę. Opcje ikon muszą być listą, więc musisz użyć visNodes lub visGroups lub przekazać bezpośrednio w nodes data.frame (patrz przykład Ionicons poniżej) Wybierz ikonę według kodu, ustaw rozmiar i kolor

nodes <- data.frame(id = 1:13, group = c("A", "C", "C", "C", "B", "B", "B", "B", "B", "B", "B", "B", "B"))
edges <- data.frame(from = c(1,1,1,2,2,2,3,3,3,4,4,4), to = c(2,3,4,5,6,7,8,9,10,11,12,13))

visNetwork(nodes, edges, width = "100%") %>%
  visGroups(groupname = "A", shape = "icon", 
            icon = list(code = "f0c0", size = 120)) %>%
  visGroups(groupname = "B", shape = "icon", 
            icon = list(code = "f007", color = "red")) %>%
  visGroups(groupname = "C", shape = "icon", 
            icon = list(code = "f0c0", color = "green")) %>%
  addFontAwesome()

Ionicons

Obsługa ikon Ionicons. W przypadku wystepowania zależności możesz w razie potrzeby użyć addIonicons(). Proces definiowania jest taki sam jak w przypadku ikon fontAwesome, z wyjątkiem tego, że musisz ustawić set = ‘Ionicons’.

nodes <- data.frame(id = 1:6, shape = "icon", icon.face = 'Ionicons',
                    icon.code = c("f4df", "f100", "f39b", "f2f7", "f3c6", "f2a8"))
edges <- data.frame(from = c(1,2,3,4,5), to = c(2,3,4,5,6))

visNetwork(nodes, edges) %>%
  addIonicons()

Opcje

Niektóre opcje niestandardowe są dostępne za pomocą visOptions().

nodes <- data.frame(id = 1:10, 
                    group = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A"),
                    label = paste("Węzeł", 1:10),
                    value = 1:10,
                    stringsAsFactors = FALSE)

edges <- data.frame(from = c(1,2,3,3,5,6,7,8,9,10),
                    to = c(2,3,4,5,4,7,8,9,6,1),
                    label = paste("Krawędź", 1:10),
                    title = paste0("<p>", 1:10,"<br>Edge Tooltip !</p>"))

Wyróżnij najbliższe

Możesz podświetlić najbliższe węzły i krawędzie, klikając węzeł za pomocą funkcji HighlightNearest. Po prostu kliknij wszędzie z wyjątkiem węzłów, aby zresetować sieć:

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visGroups(groupname = "A", 
            shape = "circle", 
            icon = list(color = "yellow")) %>%
  visGroups(groupname = "B", 
            shape = "circle", 
            icon = list(color = "red")) %>%
  visGroups(groupname = "C", 
            shape = "circle", 
            icon = list(color = "green")) %>%
  visOptions(highlightNearest = TRUE) %>%
  visLayout(randomSeed = 1337)

Możliwe jest teraz kontrolowanie stopnia głębokości, a włączenie tej opcji umożliwia również najeżdżanie na węzły (najechanie). Po najechaniu kursorem możesz nadal używać kliknięcia, aby ustawić widok :

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visGroups(groupname = "A", 
            shape = "circle", 
            icon = list(color = "yellow")) %>%
  visGroups(groupname = "B", 
            shape = "circle", 
            icon = list(color = "red")) %>%
  visGroups(groupname = "C", 
            shape = "circle", 
            icon = list(color = "green")) %>%
  visOptions(highlightNearest = list(enabled = T, degree = 2, hover = T)) %>%
  visLayout(randomSeed = 123)

Ta funkcja jest dostępna również z obrazami i ikonami:

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visGroups(groupname = "A", 
            shape = "icon", 
            icon = list(code = "f007", color = "cyan")) %>%
  visGroups(groupname = "B", 
            shape = "icon", 
            icon = list(code = "f007", color = "magenta")) %>%
  visGroups(groupname = "C", 
            shape = "icon", 
            icon = list(code = "f007", color = "black")) %>%
  visOptions(highlightNearest = list(enabled =TRUE, degree = 2, hover = T)) %>%
  addFontAwesome() %>%
  visLayout(randomSeed = 123)

Wybierz według identyfikatora węzła

Możesz również wybrać węzeł według id/etykiety z listą za pomocą nodesIdSelection:

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visGroups(groupname = "A", 
            shape = "circle", 
            icon = list(color = "yellow")) %>%
  visGroups(groupname = "B", 
            shape = "circle", 
            icon = list(color = "red")) %>%
  visGroups(groupname = "C", 
            shape = "circle", 
            icon = list(color = "green")) %>%
  visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
  visLayout(randomSeed = 2022)

Wybierz według kolumny

Wybierz podzbiór węzłów według wartości kolumny za pomocą selectedBy. Węzły mogą mieć wiele grup przy użyciu wartości oddzielonych przecinkami:

w “autoryzowanej” kolumnie

visNetwork(nodes, edges, height = "500px", width = "100%") %>%
  visGroups(groupname = "A", 
            shape = "circle", 
            icon = list(color = "yellow")) %>%
  visGroups(groupname = "B", 
            shape = "circle", 
            icon = list(color = "red")) %>%
  visGroups(groupname = "C", 
            shape = "circle", 
            icon = list(color = "green")) %>%
  visOptions(selectedBy = "group") %>%
  visLayout(randomSeed = 505)

w nowej kolumnie z wieloma grupami

nodes$sample <- paste(sample(LETTERS[1:3], nrow(nodes), replace = TRUE),
                      sample(LETTERS[1:3], nrow(nodes), replace = TRUE), 
                      sep = ",")
nodes$label <- nodes$sample

visNetwork(nodes, edges, height = "500px", width = "100%") %>%
  visGroups(groupname = "A", 
            shape = "circle", 
            icon = list(color = "yellow")) %>%
  visGroups(groupname = "B", 
            shape = "circle", 
            icon = list(color = "red")) %>%
  visGroups(groupname = "C", 
            shape = "circle", 
            icon = list(color = "green")) %>%
  visOptions(selectedBy = list(variable = "sample", multiple = T)) %>%
  visLayout(randomSeed = 123)

Opcje dostosowywania

Dostępnych jest wiele funkcji umożliwiających dostosowanie selectedBy & nodesIdSelection, na przykład:

wartości : kontroluj dostępne wartości na liście wybrane: zainicjuj wybór styl: dostosuj css listy To jest przykład bazujacy na nodesIdSelection :

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visOptions(highlightNearest = TRUE, 
              nodesIdSelection = list(enabled = TRUE,
                                 selected = "8",
                                 values = c(5:10),
                                 style = 'width: 200px; height: 26px;
                                 background: #f8f8f8;
                                 color: darkblue;
                                 border:none;
                                 outline:none;')) %>%
  visLayout(randomSeed = 123)

Zwiń / Rozwiń węzły

nodes <- data.frame(id = 1:15, label = paste("Label", 1:15),
 group = sample(LETTERS[1:3], 15, replace = TRUE))

edges <- data.frame(from = trunc(runif(15)*(15-1))+1,
 to = trunc(runif(15)*(15-1))+1)
 
# keeping all parent node attributes  
visNetwork(nodes, edges) %>% visEdges(arrows = "to") %>%
 visOptions(collapse = TRUE)

Manipulacja danymi

Korzystając z manipulacji, możesz edytować swoją sieć:

Dodaj/usuń węzły/krawędzie Zmień linki

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visOptions(manipulation = TRUE) %>%
  visLayout(randomSeed = 123)

Przykład „Nedznicy”

nodes <- jsonlite::fromJSON("https://raw.githubusercontent.com/datastorm-open/datastorm-open.github.io/master/visNetwork/data/nodes_miserables.json")

edges <- jsonlite::fromJSON("https://raw.githubusercontent.com/datastorm-open/datastorm-open.github.io/master/visNetwork/data/edges_miserables.json")


visNetwork(nodes, edges, height = "700px", width = "100%") %>%
  visOptions(selectedBy = "group", 
             highlightNearest = TRUE, 
             nodesIdSelection = TRUE) %>%
  visPhysics(stabilization = FALSE)

Uklad

Układ można konfigurować za pomocą funkcji visLayout() i visHierarchicalLayout().

Ustawianie ziarna

Węzły są początkowo rozmieszczone losowo. Oznacza to, że ustalony wynik jest za każdym razem inny. Jeśli podasz losowe ziarno ręcznie (randomSeed), układ będzie za każdym razem taki sam.

Układ hierarchiczny

Możesz używać i kontrolować układ hierarchiczny z niektórymi opcjami:

levelSeparation- odległość między różnymi poziomami. direction- kierunek układu hierarchicznego. sortMethod- algorytm używany do określania poziomów węzłów na podstawie danych

nodes <- data.frame(id = 1:7)
edges <- data.frame(from = c(1,2,2,2,3,3),
 to = c(2,3,4,5,6,7))
visNetwork(nodes, edges, width = "100%") %>% 
  visEdges(arrows = "from") %>% 
  visHierarchicalLayout()
visNetwork(nodes, edges, width = "100%") %>% 
  visEdges(arrows = "from") %>% 
  visHierarchicalLayout(direction = "LR", levelSeparation = 500)

Możliwe jest również zdefiniowanie poziomu każdego węzła:

  nodes <- data.frame(id = 1:4, level = c(2, 1, 1, 1))
edges <- data.frame(from = c(1, 1, 1),
 to = c(2,3,4))

Z poziomem wezla:

visNetwork(nodes, edges, width = "100%") %>% 
  visEdges(arrows = "from") %>% 
  visHierarchicalLayout()

Brak poziomu wezla:

nodes$level <- NULL
visNetwork(nodes, edges, width = "100%") %>% 
  visEdges(arrows = "from") %>% 
  visHierarchicalLayout()

Pakiet Igraph

Od visNetwork_0.2.1 możliwe jest powiązanie funkcji pakietu igraph z funkcjami visNetwork. Użyj układu igraph do obliczenia współrzędnych w celu szybkiego renderowania za pomocą visIgraphLayout() Przekształć sieć igraph w sieć visNetwork za pomocą visIgraph() lub toVisNetworkData()

Użyj układu Igraph

Dzięki visIgraphLayout() możesz wykorzystać wszystkie dostępne układy w igraph i obliczyć współrzędne przed wysłaniem do vis.js :

nnodes <- 100
nnedges <- 200

nodes <- data.frame(id = 1:nnodes)
edges <- data.frame(from = sample(1:nnodes, nnedges, replace = T),
                    to = sample(1:nnodes, nnedges, replace = T))
visNetwork(nodes, edges, height = "500px") %>%
  visIgraphLayout() %>%
  visNodes(size = 10)
visNetwork(nodes, edges, height = "500px") %>%
  visIgraphLayout(layout = "layout_in_circle") %>%
  visNodes(size = 10) %>%
  visOptions(highlightNearest = list(enabled = T, hover = T), 
             nodesIdSelection = T)

Użyj sieci Igraph

visIgraph bezpośrednio przekształca sieć igraph w visNetwork. Możesz również użyć toVisNetworkData, aby po prostu uzyskać dane w formacie visNetwork:

library("igraph", quietly = TRUE, warn.conflicts = FALSE, verbose = FALSE)
## Warning: package 'igraph' was built under R version 4.0.5
igraph_network <- graph.famous("Walther")

plot(igraph_network)

dane i wykres:

data <- toVisNetworkData(igraph_network)
visNetwork(nodes = data$nodes, edges = data$edges, height = "500px")

lub tylko wykres:

visIgraph(igraph_network)

Wydajnosc

Przy domyślnych/niektórych opcjach renderowanie sieci może zająć dużo czasu. Oto kilka sposobów na poprawę wydajności:

Domyślnie, jeśli nie przekazujemy żadnych informacji o współrzędnych, vis.js oblicza współrzędne dynamicznie i czeka na stabilizację przed renderowaniem. Możesz wyłączyć lub kontrolować stabilizację za pomocą visPhysics :

visNetwork(nodes, edges) %>%
  visPhysics(stabilization = FALSE)

Kolejną wskazówką jest wyłączenie gładkiej krzywej dla krawędzi. To prowadzi do lepszej wydajnosci:

visNetwork(nodes, edges) %>%
  visEdges(smooth = FALSE)

Możliwe jest powiązanie funkcji pakietu igraph z funkcjami visNetwork. Najlepszym sposobem na wydłużenie czasu kreślenia grafu jest użycie układu igraph do obliczenia współrzędnych wcześniej za pomocą visIgraphLayout():

visNetwork(nodes, edges) %>%
  visIgraphLayout()

Koszyk

Od wersji visNetwork_2.0.0 możesz wizualizować drzewa klasyfikacji i regresji z danych wyjściowych pakietu rpart, używając po prostu visTree :

Drzewo klasyfikacyjne

res <- rpart(Species~., data=iris)
visTree(res, main = "Iris classification Tree", width = "100%")

Drzewo regresji

res <- rpart(Petal.Length~., data=iris)
visTree(res, edgesFontSize = 14, nodesFontSize = 16, width = "100%")
data("solder")
res <- rpart(Opening~., data = solder, control = rpart.control(cp = 0.00005))
visTree(res, height = "800px", nodesPopSize = TRUE, minNodeSize = 10, 
        maxNodeSize = 30, width = "100%")

Użycie w shiny

Spójrz na visTreeEditor, aby edytować i wrócić do sieci, oraz na visTreeModuleServer, aby użyć niestandardowego modułu drzewa w R.

Shiny

Korzystaj z sieci w Shiny dzięki visNetworkOutput i renderVisNetwork

require(shiny)
require(visNetwork)

server <- function(input, output) {
  output$mynetworkid <- renderVisNetwork({
    # minimal example
    nodes <- data.frame(id = 1:3)
    edges <- data.frame(from = c(1,2), to = c(1,3))
    
    visNetwork(nodes, edges)
  })
}

ui <- fluidPage(
    visNetworkOutput("mynetworkid")
)

shinyApp(ui = ui, server = server)

Interakcje Shiny

dane wejściowe są tworzone po zainicjowaniu sieci: input$mynetworkid_initialized z nodesIdSelection możesz uzyskać dostęp do nowych danych wejściowych z bieżącą wartością wyboru:

   output$mynetworkid <- renderVisNetwork({ visOptions(nodesIdSelection = TRUE)
  }) 
# utworzono input$mynetworkid_selected

z selectedBy, możesz uzyskać dostęp do nowego wejścia(input):

output$mynetwork <- renderVisNetwork({...visOptions(nodesIdSelection = TRUE)
  }) 
# utworzono input$mynetworkid_selectedBy

dzięki manipulation możesz uzyskać dostęp do nowych danych wejściowych z informacjami o manipulacji:

output$mynetwork <- renderVisNetwork({
  visOptions(manipulation = TRUE)
  }) 
# utworzono input$mynetworkid__graphChange

Zmodyfikuj swoją sieć za pomocą visNetworkProxy

Aby nie przerysowywać całej sieci, możesz użyć funkcji visNetworkProxy w shiny, a następnie zmienić konfigurację swojej sieci bez jej przerysowywania.

Możesz korzystać z prawie wszystkich funkcji dostępnych w visNetworkProxy, a nawet z niektórych funkcji specjalnych.

klasyczne funkcje: visNodes, visEdges, visGroups, visOptions (>=0.2.2), visPhysics, visInteraction, visLayout & visHierarchicalLayout

funkcje specjalne (metody vis.js):

visFocus : skoncentruj się na jednym węźle docelowym visFit : dopasuj widok do jednego lub kilku węzłów visUpdateNodes / visUpdateEdges : aktualizuj / dodaj dane visRemoveNodes / visRemoveEdges : usuń dane visSelectNodes / visSelectEdges / visSetSelection: wybór a także visRedraw, visStabilize,visSetData,visGetPositions,visMoveNode,visUnselectAll

require(shiny)
require(visNetwork)

server <- function(input, output) {
  output$network_proxy_nodes <- renderVisNetwork({
    nodes <- data.frame(id = 1:3)
    edges <- data.frame(from = c(1,2), to = c(1,3))
    
    visNetwork(nodes, edges) %>% visNodes(color = "blue")
  })
  
  
  observe({
    visNetworkProxy("network_proxy_nodes") %>%
      visFocus(id = input$Focus, scale = 4)
  })
  
  observe({
    visNetworkProxy("network_proxy_nodes") %>%
      visNodes(color = input$color)
  })
  
}

ui <- fluidPage(
  fluidRow(
    column(
      width = 4,
      selectInput("color", "Color :",
                    c("blue", "red", "green")),
      selectInput("Focus", "Focus on node :",
                    c(1:3))
    ),
    column(
      width = 8,
      visNetworkOutput("network_proxy_nodes", height = "400px")
    )
  )
)

Zbuduj swój własny input

Dzięki świetnym widżetom html można również tworzyć niestandardowe, dane wejściowe Shiny z visNetwork. W tym celu wystarczy użyć funkcji Shiny.onInputChange w evencie javascript. To jest przykład przekazywania identyfikatora węzła po najechaniu na niego kursorem:

library(visNetwork)
library(shiny)

server <- function(input, output) {
  output$network <- renderVisNetwork({
    # minimal example
    nodes <- data.frame(id = 1:3, label = 1:3)
    edges <- data.frame(from = c(1,2), to = c(1,3))
    
    visNetwork(nodes, edges) %>%
      visInteraction(hover = TRUE) %>%
      visEvents(hoverNode = "function(nodes) {
        Shiny.onInputChange('current_node_id', nodes);
      ;}")
  })
  
  output$shiny_return <- renderPrint({
    input$current_node_id
  })
}

ui <- fluidPage(
  visNetworkOutput("network"),
  verbatimTextOutput("shiny_return")
)

Interakcje

Możemy kontrolować interakcje sieci za pomocą visInteraction() :

Zamrożona siec

Mamy kilka ciekawych opcji pozwalających nam kontrolować zachowanie wykresu:

dragNodes : opcja pozwalająca kontrolować zaznaczanie i poruszanie węzłami (klikanie na węzeł i przeciąganie myszą) dragView : opcja pozwalająca kontrolować ruch całej sieci (klikanie gdziekolwiek poza węzłem i przeciąganie myszą) zoomView : opcja pozwalająca włączyć lub wyłączyć zoomowanie (scroll myszy)

nodes <- data.frame(id = 1:10, 
                    group = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A"),
                    label = paste("Węzeł", 1:10),
                    value = 1:10,
                    stringsAsFactors = FALSE)

edges <- data.frame(from = c(1,2,3,3,5,6,7,8,9,10),
                    to = c(2,3,4,5,4,7,8,9,6,1),
                    label = paste("Krawędź", 1:10),
                    title = paste0("<p>", 1:10,"<br>Edge Tooltip !</p>"))
visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visInteraction(dragNodes = FALSE, 
                 dragView = FALSE, 
                 zoomView = FALSE) %>%
  visLayout(randomSeed = 123)

Ukrywanie krawędzi/węzłów podczas przeciągania

Opcja ta może zwięszyć ogólną wydajność.

hideEdgesOnDrag : opcja odpowiedzialna za ukrywanie krawędzi podczas poruszania siecią hideNodesOnDrag : opcja odpowiedzialna za ukrywanie węzłów podczas poruszania siecią

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visInteraction(hideEdgesOnDrag = TRUE) %>%
  visLayout(randomSeed = 123)

Przyciski nawigacyjne

Możemy pokazać przyciski nawigacyjne za pomocą nawigacjiButtons :

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visInteraction(navigationButtons = TRUE)

Dodatkowe opcje

keyboard : włącz manipulację klawiaturą zamiast myszą hover i hoverConnectedEdges : sterowanie hover selectable: wyłącz zaznaczanie węzłów i krawędzi tooltipDelay : ustawia opóźnienie przed wyświetleniem pop-up …

visNetwork(nodes, edges, height = "500px", width = "100%") %>% 
  visInteraction(keyboard = TRUE, tooltipDelay = 0)

Fizyka

Fizyka sieci ma wiele opcji konfiguracji

Używając funkcji visPhysics() możesz bawić się fizyką sieci: -wybierz ‘solver’ („barnesHut”, „odpychanie”, „hierarchicalRepulsion”, „forceAtlas2Based”) i ustaw opcje

Kontroluj proces ‘stabilization’: -baw się z ‘maxVelocity’ i ‘minVelocity’ -wyłącz stabilizację dla renderowania początkowej sieci i zobacz procesy stabilizacji

nodes <- data.frame(id = 1:10, 
                    group = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A"),
                    label = paste("Węzeł", 1:10),
                    value = 1:10,
                    stringsAsFactors = FALSE)

edges <- data.frame(from = c(1,2,3,3,5,6,7,8,9,10),
                    to = c(2,3,4,5,4,7,8,9,6,1),
                    label = paste("Krawędź", 1:10),
                    title = paste0("<p>", 1:10,"<br>Edge Tooltip !</p>"))
visNetwork(nodes, edges, height = "500px", width = "100%") %>%
 visPhysics(solver = "forceAtlas2Based", 
            forceAtlas2Based = list(gravitationalConstant = -500))
visNetwork(nodes, edges, height = "500px", width = "100%") %>%
 visPhysics(solver = "barnesHut")

Narzedzia do konfiguracji

Użyj visConfigure(), aby skonfigurować i wyświetlić opcje bezpośrednio na swojej sieci

nodes <- data.frame(id = 1:10, 
                    group = c("A", "B", "C", "A", "B", "C", "A", "B", "C", "A"),
                    label = paste("Węzeł", 1:10),
                    value = 1:10,
                    stringsAsFactors = FALSE)

edges <- data.frame(from = c(1,2,3,3,5,6,7,8,9,10),
                    to = c(2,3,4,5,4,7,8,9,6,1),
                    label = paste("Krawędź", 1:10),
                    title = paste0("<p>", 1:10,"<br>Edge Tooltip !</p>"))
# don't look in RStudio viewer
visNetwork(nodes, edges, width = "100%")

Wiecej eksperymentalnych opcji

Events

Dodaj event javascript za pomocą visEvents()

nodes <- data.frame(id = 1:3, label = 1:3)
edges <- data.frame(from = c(1,2), to = c(1,3))

visNetwork(nodes, edges) %>%
 visEvents(selectNode = "function(properties) {
      alert('selected nodes ' + this.body.data.nodes.get(properties.nodes[0]).id);}")

Eksport

Użyj visSave(), aby zapisać sieć w pliku .html i visExport(), aby zapisać jako .png z Shiny :

network <- visNetwork(nodes, edges, width = "100%")
network %>% visSave(file = "network.html")
# same as
visSave(network, file = "network.html")
# or
htmlwidgets::saveWidget(network, "network.html")

Użyj danych języka DOT

visNetwork(dot = 'dinetwork {1 -> 1 -> 2; 2 -> 3; 2 -- 4; 2 -> 1 }', 
           width = "100%")

Użyj pliku eksportu gephi json

visNetwork(gephi = 'WorldCup2014.json')

Grupowanie

Dostępne są niektóre pierwsze (eksperymentalne) funkcje:

visClusteringByColor() visClusteringByPołączenie() visClusteringByHubsize() visClusteringByGroup() visClusteringOutliers() Możesz otwierać klastry, klikając dwukrotnie i ponownie klastrować za pomocą przycisku.

nodes <- data.frame(id = 1:10, label = paste("Label", 1:10), 
   group = sample(c("A", "B"), 10, replace = TRUE)) 

edges <- data.frame(from = c(2,5,10), to = c(1,2,10))

visNetwork(nodes, edges, height = "400px", width = "100%") %>%
  visGroups(groupname = "A", color = "red", shape = "square") %>%
  visGroups(groupname = "B", color = "yellow", shape = "triangle") %>%
  visClusteringByColor(colors = c("red")) %>%
  visClusteringByGroup(groups = c("B")) %>%
  visLegend()

KONIEC

Dziękujemy za zapoznanie się z naszym poradnikiem. Mamy nadzieje, że znacząco ułatwi posługiwanie się pakietem visNetwork i pokaże studentom lub programistom języka R, jak szerokie pole do popisu, jeśli chodzi o wykresy, dają jego pakiety.