QBoard » Advanced Visualizations » Viz - Python » How to make a sunburst plot in R or Python?

How to make a sunburst plot in R or Python?

  • So far I have been unable to find an R library that can create a sunburst plot like those by John Stasko. Anyone knows how to accomplish that in R or Python?

      September 25, 2020 12:59 PM IST
    0
  • Python version of sunburst diagram using matplotlib bars in polar projection:

    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()

    Example, how this function can be used:

    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)


     

    This post was edited by Shivakumar Kota at September 25, 2020 3:04 PM IST
      September 25, 2020 2:16 PM IST
    0
  • Theres a package called ggsunburst. Sadly is not in CRAN but you can install following the instruction in the website: http://genome.crg.es/~didac/ggsunburst/ggsunburst.html.



    src="https://d3ftmvynp162pm.cloudfront.net/public/album_photo/3a/fb/02/db0f014f4bf9e9b685ce3566df80ab2e.png">


    Hope it helps to people who still looking for a good package like this.

    This post was edited by Pranav B at September 25, 2020 3:20 PM IST
      September 25, 2020 3:10 PM IST
    0
  • There are only a couple of libraries that I know of that do this natively:

    1. The Javascript Infovis Toolkit (jit) (example).
    2. D3.js
    3. OCaml's Simple Plot Tool (SPT).

    Neither of these are in Python or R, but getting a python/R script to write out a simple JSON file that can be loaded by either of the javascript libraries should be pretty achievable.

      September 25, 2020 3:21 PM IST
    0
  • Since Pranav B mentioned ggsunburst, here I post an example for reproducing the sunburst by sirex.

    It is not exactly the same because in ggsunburst the angle of a node is equal to the sum of the angles of its children nodes.

    # 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)


      September 25, 2020 3:27 PM IST
    0