Wedgeplot gridplot


#1

Hi!

I’m trying to get a square categorical gridplot of piecharts/wedges working. However, I can’t seem to get the scaling in a go.layout.Grid to be square, nor can I get “gridlines”, “axis” ticks or something similar in. This may be stretching the capabilities of go.layout.Grid and go.Pie a little, but perhaps any of you see a solution!

The code:

import plotly.offline as py
import plotly.graph_objs as go
import random
nodes = ["apple", "pear", "pineapple", "grape", "passion fruit"]
ews = ["acidity", "sugar", "texture", "juice"]
rng = range(len(nodes))
edge_weights = [[[random.randint(0,1)*random.randint(0,1)*random.randint(1,100) for ew in ews] for i in rng] for j in rng]
pies = []
for i, source in enumerate(nodes):
    for j, target in enumerate(nodes):
        pie = go.Pie(labels=ews, values=edge_weights[i][j], text=None, domain=go.pie.Domain(row=i, column=j), textinfo='none', hoverinfo='skip')
        pies.append(pie)  
grid = go.layout.Grid(rows=len(nodes), columns=len(nodes), pattern="coupled", xgap=0.1, ygap=0.1)
layout = go.Layout(grid=grid, autosize=False)
fig=go.Figure(pies, layout=layout)
py.iplot(fig)


So, I’m trying to get the following things in:

  • xaxes scaling w.r.t. yaxes should be 1:1 (e.g. the gaps between piecharts)
  • axes labels (like tick marks in a categorical plot)
  • grid lines

Any ideas?


#2

Hi @Tiemen,

There’s nothing directly built in to do this, but here’s an approach that I got working.

import plotly.offline as py
import plotly.graph_objs as go
import random
nodes = ["apple", "pear", "pineapple", "grape", "passion fruit"]
ews = ["acidity", "sugar", "texture", "juice"]
rng = range(len(nodes))
edge_weights = [[[random.randint(0,1)*random.randint(0,1)*random.randint(1,100) for ew in ews] for i in rng] for j in rng]
pies = []
for i, source in enumerate(nodes):
    for j, target in enumerate(nodes):
        pie = go.Pie(labels=ews, values=edge_weights[i][j], text=None, domain=go.pie.Domain(row=i, column=j), textinfo='none', hoverinfo='skip')
        pies.append(pie)  
grid = go.layout.Grid(rows=len(nodes), columns=len(nodes), pattern="coupled", xgap=0.1, ygap=0.1)
layout = go.Layout(grid=grid, autosize=False)

# Make plot area square
layout.margin = {'l': margin, 'r': margin, 't': margin, 'b': margin}
layout.width = 500
layout.height = 500

# Add empty scatter trace to cause axes to show up
scatt = fig.add_scatter(x=[None], y=[None])

# Push shrink grid a small amount to better align ticks
layout.grid.domain.x = [0.01, 0.99]
layout.grid.domain.y = [0.01, 0.99]

# Expand x and y axes to cover full grid
layout.xaxis.domain = [0, 1]
layout.yaxis.domain = [0, 1]

# Set axis range
layout.yaxis.range = [-0.5, len(nodes) - 0.5]
layout.xaxis.range = [-0.5, len(nodes) - 0.5]

# Remove zero lines
layout.xaxis.zeroline = False
layout.yaxis.zeroline = False

# Add outside ticks
layout.xaxis.ticks = 'outside'
layout.yaxis.ticks = 'outside'

# Position ticks and grid lines at each row/column
layout.xaxis.tickvals = list(range(len(nodes)))
layout.yaxis.tickvals = list(range(len(nodes)))

# Set tick text to categorical labels
layout.xaxis.ticktext = nodes
layout.yaxis.ticktext = nodes

# Traces list
traces = pies + [go.Scatter(x=[None], y=[None], showlegend=False)]

# Prevent pan/zoom actions because they would
# cause pies and grid to get of of alignment
layout.dragmode = False

fig=go.Figure(traces, layout=layout)
py.iplot(fig)

newplot%20(2)

See the inline comments for some explanations.

Hope that helps!
-Jon


#3

Thank you for sharing your approach! The hidden trace/axis trick sure is good to know. It’s not as pretty as you’d like, but it gets the job done.