Converting a 'custom' radar graph from matplotlib to bokeh

Hi!

I want to convert this radar graph, taken from stackoverflow, into a bokeh plot. Is this possible, or does bokeh not support radar graphs?

Whenever I run show(mpl.to_bokeh()) on this code I just get an empty plot

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns # improves plot aesthetics
def _invert(x, limits):
“”“inverts a value x on a scale from
limits[0] to limits[1]”""
return limits[1] - (x - limits[0])
def _scale_data(data, ranges):
“”“scales data[1:] to ranges[0],
inverts if the scale is reversed”""
for d, (y1, y2) in zip(data[1:], ranges[1:]):
assert (y1 <= d <= y2) or (y2 <= d <= y1)
x1, x2 = ranges[0]
d = data[0]
if x1 > x2:
d = _invert(d, (x1, x2))
x1, x2 = x2, x1
sdata = [d]
for d, (y1, y2) in zip(data[1:], ranges[1:]):
if y1 > y2:
d = _invert(d, (y1, y2))
y1, y2 = y2, y1
sdata.append((d-y1) / (y2-y1) * (x2 - x1) + x1)
return sdata
class ComplexRadar():
def init(self, fig, variables, ranges,
n_ordinate_levels=6):
angles = np.arange(0, 360, 360./len(variables))
axes = [fig.add_axes([0.1,0.1,0.9,0.9],polar=True,
label = “axes{}”.format(i)) for i in range(len(variables))]
l, text = axes[0].set_thetagrids(angles, labels=variables)
[txt.set_rotation(angle-90) for txt, angle in zip(text, angles)]
for ax in axes[1:]:
ax.patch.set_visible(False)
ax.grid(“off”)
ax.xaxis.set_visible(False)
for i, ax in enumerate(axes):
grid = np.linspace(*ranges[i], num=n_ordinate_levels)
gridlabel = ["{}".format(round(x,2)) for x in grid]
if ranges[i][0] > ranges[i][1]:
grid = grid[::-1] # hack to invert grid

gridlabels aren’t reversed

gridlabel[0] = “” # clean up origin
ax.set_rgrids(grid, labels=gridlabel,
angle=angles[i])
#ax.spines[“polar”].set_visible(False)
ax.set_ylim(*ranges[i])

variables for plotting

self.angle = np.deg2rad(np.r_[angles, angles[0]])
self.ranges = ranges
self.ax = axes[0]
def plot(self, data, *args, **kw):
sdata = scale_data(data, self.ranges)
self.ax.plot(self.angle, np.r
[sdata, sdata[0]], *args, **kw)
def fill(self, data, *args, **kw):
sdata = scale_data(data, self.ranges)
self.ax.fill(self.angle, np.r
[sdata, sdata[0]], *args, **kw)

example data

variables = (“Normal Scale”, “Inverted Scale”, “Inverted 2”, “Normal Scale 2”, “Normal 3”, “Normal 4 %”, “Inverted 3 %”)
data = (1.76, 1.1, 1.2, 4.4, 3.4, 86.8, 20)
ranges = [(0.1, 2.3), (1.5, 0.3), (1.3, 0.5),
(1.7, 4.5), (1.5, 3.7), (70, 87), (100, 10)] # plotting
fig1 = plt.figure(figsize=(6, 6))
radar = ComplexRadar(fig1, variables, ranges)
radar.plot(data)
radar.fill(data, alpha=0.2)
plt.show()

Hi,

It is definitely possible to reproduce a plot like that using native Bokeh APIs (i.e., by using bokeh.models or bokeh.plotting directly).

But I very much doubt that mpl.to_bokeh will work on something so complex. Bokeh's MPL support is relies on a third party library that is incomplete, and also no longer maintained. Bokeh's MPL compat will not see new effort until or unless Matplotlib Enhancement Proposal 25 is implemented. In the mean time, it is provided purely AS-IS, just in case it happens to be useful in some particular cases.

Thanks,

Bryan

···

On Dec 30, 2016, at 1:58 PM, Sayaaa <[email protected]> wrote:

Hi!

I want to convert this radar graph, taken from stackoverflow, into a bokeh plot. Is this possible, or does bokeh not support radar graphs?

Whenever I run show(mpl.to_bokeh()) on this code I just get an empty plot

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns # improves plot aesthetics

def _invert(x, limits):
    """inverts a value x on a scale from
    limits[0] to limits[1]"""
    return limits[1] - (x - limits[0])

def _scale_data(data, ranges):
    """scales data[1:] to ranges[0],
    inverts if the scale is reversed"""
    for d, (y1, y2) in zip(data[1:], ranges[1:]):
        assert (y1 <= d <= y2) or (y2 <= d <= y1)
    x1, x2 = ranges[0]
    d = data[0]
    if x1 > x2:
        d = _invert(d, (x1, x2))
        x1, x2 = x2, x1
    sdata = [d]
    for d, (y1, y2) in zip(data[1:], ranges[1:]):
        if y1 > y2:
            d = _invert(d, (y1, y2))
            y1, y2 = y2, y1
        sdata.append((d-y1) / (y2-y1)
                     * (x2 - x1) + x1)
    return sdata

class ComplexRadar():
    def __init__(self, fig, variables, ranges,
                 n_ordinate_levels=6):
        angles = np.arange(0, 360, 360./len(variables))

        axes = [fig.add_axes([0.1,0.1,0.9,0.9],polar=True,
                label = "axes{}".format(i))
                for i in range(len(variables))]
        l, text = axes[0].set_thetagrids(angles,
                                         labels=variables)
        [txt.set_rotation(angle-90) for txt, angle
             in zip(text, angles)]
        for ax in axes[1:]:
            ax.patch.set_visible(False)
            ax.grid("off")
            ax.xaxis.set_visible(False)
        for i, ax in enumerate(axes):
            grid = np.linspace(*ranges[i],
                               num=n_ordinate_levels)
            gridlabel = ["{}".format(round(x,2))
                         for x in grid]
            if ranges[i][0] > ranges[i][1]:
                grid = grid[::-1] # hack to invert grid
                          # gridlabels aren't reversed
            gridlabel[0] = "" # clean up origin
            ax.set_rgrids(grid, labels=gridlabel,
                         angle=angles[i])
            #ax.spines["polar"].set_visible(False)
            ax.set_ylim(*ranges[i])
        # variables for plotting
        self.angle = np.deg2rad(np.r_[angles, angles[0]])
        self.ranges = ranges
        self.ax = axes[0]
    def plot(self, data, *args, **kw):
        sdata = _scale_data(data, self.ranges)
        self.ax.plot(self.angle, np.r_[sdata, sdata[0]], *args, **kw)
    def fill(self, data, *args, **kw):
        sdata = _scale_data(data, self.ranges)
        self.ax.fill(self.angle, np.r_[sdata, sdata[0]], *args, **kw)

# example data
variables = ("Normal Scale", "Inverted Scale", "Inverted 2",
            "Normal Scale 2", "Normal 3", "Normal 4 %", "Inverted 3 %")
data = (1.76, 1.1, 1.2,
        4.4, 3.4, 86.8, 20)
ranges = [(0.1, 2.3), (1.5, 0.3), (1.3, 0.5),
         (1.7, 4.5), (1.5, 3.7), (70, 87), (100, 10)]
# plotting
fig1 = plt.figure(figsize=(6, 6))
radar = ComplexRadar(fig1, variables, ranges)
radar.plot(data)
radar.fill(data, alpha=0.2)
plt.show()

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/acde1972-5698-4e8a-aa22-146cfd9a3292%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.