Comment faire un scénario sunburst en R ou en Python?

Jusqu'à présent j'ai été incapable de trouver une bibliothèque R qui peut créer un scénario sunburst comme ceux par John Stako. Quelqu'un sait comment accomplir cela en R ou en Python?

Sunburst

33
demandé sur VividD 2012-10-17 07:41:44

7 réponses

version Python du diagramme de sunburst utilisant des barres matplotlib dans la projection polaire:

import numpy as np
import matplotlib.pyplot as plt

def sunburst(nodes, total=np.pi * 2, offset=0, level=0, ax=None):
    ax = ax or plt.subplot(111, projection='polar')

    if level == 0 and len(nodes) == 1:
        label, value, subnodes = nodes[0]
        ax.bar([0], [0.5], [np.pi * 2])
        ax.text(0, 0, label, ha='center', va='center')
        sunburst(subnodes, total=value, level=level + 1, ax=ax)
    elif nodes:
        d = np.pi * 2 / total
        labels = []
        widths = []
        local_offset = offset
        for label, value, subnodes in nodes:
            labels.append(label)
            widths.append(value * d)
            sunburst(subnodes, total=total, offset=local_offset,
                     level=level + 1, ax=ax)
            local_offset += value
        values = np.cumsum([offset * d] + widths[:-1])
        heights = [1] * len(nodes)
        bottoms = np.zeros(len(nodes)) + level - 0.5
        rects = ax.bar(values, heights, widths, bottoms, linewidth=1,
                       edgecolor='white', align='edge')
        for rect, label in zip(rects, labels):
            x = rect.get_x() + rect.get_width() / 2
            y = rect.get_y() + rect.get_height() / 2
            rotation = (90 + (360 - np.degrees(x) % 180)) % 360
            ax.text(x, y, label, rotation=rotation, ha='center', va='center') 

    if level == 0:
        ax.set_theta_direction(-1)
        ax.set_theta_zero_location('N')
        ax.set_axis_off()

Exemple, comment cette fonction peut être utilisée:

data = [
    ('/', 100, [
        ('home', 70, [
            ('Images', 40, []),
            ('Videos', 20, []),
            ('Documents', 5, []),
        ]),
        ('usr', 15, [
            ('src', 6, [
                ('linux-headers', 4, []),
                ('virtualbox', 1, []),

            ]),
            ('lib', 4, []),
            ('share', 2, []),
            ('bin', 1, []),
            ('local', 1, []),
            ('include', 1, []),
        ]),
    ]),
]

sunburst(data)

python matplotlib sunburst diagram

18
répondu sirex 2017-10-17 13:16:13

Vous pouvez même construire une version interactive assez facilement avec R maintenant:

# devtools::install_github("timelyportfolio/sunburstR")

library(sunburstR)
# read in sample visit-sequences.csv data provided in source
# https://gist.github.com/kerryrodden/7090426#file-visit-sequences-csv
sequences <- read.csv(
  system.file("examples/visit-sequences.csv",package="sunburstR")
  ,header=F
  ,stringsAsFactors = FALSE
)

sunburst(sequences)

enter image description here

...et lorsque vous déplacez votre souris au-dessus d'elle, la magie se produit:

enter image description here

Modifier

Le site officiel de ce package peut être trouvé ici (avec de nombreux exemples!):https://github.com/timelyportfolio/sunburstR

pointe du chapeau à @timelyportfolio qui a créé cet impressionnant morceau de code!

24
répondu vonjd 2015-10-01 15:38:34

vous pouvez créer quelque chose comme un coup de soleil en utilisant geom_tileggplot2 paquet. Commençons par créer des données aléatoires:

require(ggplot2); theme_set(theme_bw())
require(plyr)
dat = data.frame(expand.grid(x = 1:10, y = 1:10),
                 z = sample(LETTERS[1:3], size = 100, replace = TRUE))

et ensuite créer l'intrigue matricielle. Ici, le x l'axe de la placette est couplé au x variable dat, le y axe y variable, et le remplissage des pixels à l' z variable. Cela donne les courbes ci-dessous:

p = ggplot(dat, aes(x = x, y = y, fill = z)) + geom_tile() 
print(p)

enter image description here

le ggplot2 package supporte toutes sortes de transformations de coordonnées, dont l'une prend un axe et le projette sur un cercle, c'est-à-dire des coordonnées polaires:

p + coord_polar()

enter image description here

Ce à peu près fait ce que vous avez besoin, maintenant, vous pouvez modifier dat pour obtenir le résultat souhaité.

11
répondu Paul Hiemstra 2012-10-29 07:48:44

Theres un paquet appelé ggsunburst. Malheureusement N'est pas dans CRAN mais vous pouvez installer en suivant les instructions sur le site web:http://genome.crg.es/~didac/ggsunburst/ggsunburst.html.

enter image description here

J'espère que cela aidera les gens qui sont encore à la recherche d'un bon paquet comme celui-ci.

Cordialement,

5
répondu jbkunst 2015-09-22 15:55:16

Il ya seulement un couple de bibliothèques que je sais de qui ne ce mode natif:

aucun de ceux-ci ne sont en Python ou R, mais obtenir un script python/R pour écrire un simple fichier JSON qui peut être chargé par l'une ou l'autre des bibliothèques javascript devrait être joli. réalisable.

3
répondu jozzas 2012-10-17 04:42:48

Voici un ggplot2 Coup de soleil avec deux couches.

L'idée de base est de faire juste un bar différent pour chaque couche, et de faire les barres plus larges pour les couches extérieures. J'ai aussi trafiqué avec l'axe des abscisses pour m'assurer qu'il n'y a pas de trou au milieu du diagramme circulaire interne. Vous pouvez ainsi contrôler l'apparence du sunburst en changeant les valeurs de la largeur et de l'axe des X.

library(ggplot2)

# make some fake data
df <- data.frame(
    'level1'=c('a', 'a', 'a', 'a', 'b', 'b', 'c', 'c', 'c'), 
    'level2'=c('a1', 'a2', 'a3', 'a4', 'b1', 'b2', 'c1', 'c2', 'c3'), 
    'value'=c(.025, .05, .027, .005, .012, .014, .1, .03, .18))

# sunburst plot
ggplot(df, aes(y=value)) +
    geom_bar(aes(fill=level1, x=0), width=.5, stat='identity') + 
    geom_bar(aes(fill=level2, x=.25), width=.25, stat='identity') + 
    coord_polar(theta='y')

enter image description here

le seul inconvénient que cela a par rapport à sunburst-logiciel spécifique, c'est qu'il suppose que vous voulez que les couches extérieures à être exhaustifs (aucun espace). Les couches externes "partiellement exhaustives" (comme dans d'autres exemples) sont certainement possibles mais plus compliquées.

pour plus d'exhaustivité, ici, il est nettoyé avec un plus beau formatage et des étiquettes:

library(data.table)

# compute cumulative sum for outer labels
df <- data.table(df)
df[, cumulative:=cumsum(value)-(value/2)]

# store labels for inner circle
inner_df <- df[, c('level1', 'value'), with=FALSE]
inner_df[, level1_value:=sum(value), by='level1']
inner_df <- unique(text_df[, c('level1', 'level1_value'), with=FALSE])
inner_df[, cumulative:=cumsum(level1_value)]
inner_df[, prev:=shift(cumulative)]
inner_df[is.na(prev), position:=(level1_value/2)]
inner_df[!is.na(prev), position:=(level1_value/2)+prev]

colors <- c('#6a3d9a', '#1F78B4', '#33A02C', '#3F146D', '#56238D', '#855CB1', '#AD8CD0', '#08619A', '#3F8DC0', '#076302', '#1B8416', '#50B74B')
colorNames <- c(unique(as.character(df$level1)), unique(as.character(df$level2)))
names(colors) <- colorNames

ggplot(df, aes(y=value, x='')) +
    geom_bar(aes(fill=level2, x=.25), width=.25, stat='identity') + 
    geom_bar(aes(fill=level1, x=0), width=.5, stat='identity') + 
    geom_text(data=inner_df, aes(label=level1, x=.05, y=position)) + 
    coord_polar(theta='y') + 
    scale_fill_manual('', values=colors) +
    theme_minimal() + 
    guides(fill=guide_legend(ncol=1)) +
    labs(title='') + 
    scale_x_continuous(breaks=NULL) + 
    scale_y_continuous(breaks=df$cumulative, labels=df$level2, 5) + 
    theme(axis.title.x=element_blank(), axis.title.y=element_blank(), panel.border=element_blank(), panel.grid=element_blank())

enter image description here

3
répondu dmp 2016-12-21 22:30:55

depuis jbkunst mentionné ggsunburst, ici je poste un exemple pour reproduire le sunburst par sirex.

Ce n'est pas exactement le même, parce que dans ggsunburst l'angle d'un nœud est égale à la somme des angles de ses nœuds enfants.

# install ggsunburst package
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("rPython")) install.packages("rPython")
install.packages("http://genome.crg.es/~didac/ggsunburst/ggsunburst_0.0.9.tar.gz", repos=NULL, type="source")
library(ggsunburst)

# dataframe
# each row corresponds to a node in the hierarchy
# parent and node are required, the rest are optional attributes
# the attributes correspond to the node, not its parent
df <- read.table(header = T, sep = ",", text = "
parent,node,size,color,dist
,/,,B,1
/,home,,D,1
home,Images, 40,E,1
home,Videos, 20,E,1
home,Documents, 5,E,1
/,usr,,D,1
usr,src,,A,1
src,linux-headers, 4,C,1.5
src,virtualbox, 1,C,1.5
usr,lib, 4,A,1
usr,share, 2,A,1
usr,bin, 1,A,1
usr,local, 1,A,1
usr,include, 1,A,1
")

write.table(df, 'df.csv', sep = ",", row.names = F)

# compute coordinates from dataframe
# "node_attributes" is used to pass the attributes other than "size" and "dist", 
# which are special attributes that alter the dimensions of the nodes
sb <- sunburst_data('df.csv', sep = ",", type = "node_parent", node_attributes = "color")

# plot
sunburst(sb, node_labels = T, node_labels.min = 10, rects.fill.aes = "color") +
  scale_fill_brewer(palette = "Set1", guide = F)

enter image description here

1
répondu didac 2018-05-12 23:52:45