Skip to content

Commit 27c5a36

Browse files
authored
Merge pull request #917 from int-brain-lab/starplot
plot to create a star plot
2 parents caa8562 + 7c9212d commit 27c5a36

File tree

3 files changed

+78
-7
lines changed

3 files changed

+78
-7
lines changed

ibllib/oneibl/registration.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
from one.converters import ConversionMixin
1414
import one.alf.exceptions as alferr
1515
from one.api import ONE
16-
from one.util import datasets2records
16+
try:
17+
from one.util import datasets2records
18+
except ImportError:
19+
from one.converters import datasets2records
1720
from iblutil.util import ensure_list
1821

1922
import ibllib

ibllib/plots/misc.py

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/usr/bin/env python
22
# -*- coding:utf-8 -*-
3+
from math import pi
4+
35
import numpy as np
46
import matplotlib.pyplot as plt
57
import scipy
@@ -274,7 +276,53 @@ def color_cycle(ind=None):
274276
return tuple(c[ind % c.shape[0], :])
275277

276278

277-
if __name__ == "__main__":
278-
w = np.random.rand(500, 40) - 0.5
279-
wiggle(w, fs=30000)
280-
Traces(w, fs=30000, color='r')
279+
def starplot(labels, radii, ticks=None, ax=None, ylim=None, color=None, title=None):
280+
"""
281+
Function to create a star plot (also known as a spider plot, polar plot, or radar chart).
282+
283+
Parameters:
284+
labels (list): A list of labels for the variables to be plotted along the axes.
285+
radii (numpy array): The values to be plotted for each variable.
286+
ticks (numpy array, optional): A list of values to be used for the radial ticks.
287+
If None, 5 ticks will be created between the minimum and maximum values of radii.
288+
ax (matplotlib.axes._subplots.PolarAxesSubplot, optional): A polar axis object to plot on.
289+
If None, a new figure and axis will be created.
290+
ylim (tuple, optional): A tuple specifying the upper and lower limits of the y-axis.
291+
If None, the limits will be set to the minimum and maximum values of radii.
292+
color (str, optional): A string specifying the color of the plot.
293+
If None, the color will be determined by the current matplotlib color cycle.
294+
title (str, optional): A string specifying the title of the plot.
295+
If None, no title will be displayed.
296+
297+
Returns:
298+
ax (matplotlib.axes._subplots.PolarAxesSubplot): The polar axis object containing the plot.
299+
"""
300+
301+
# What will be the angle of each axis in the plot? (we divide the plot / number of variable)
302+
angles = [n / float(radii.size) * 2 * pi for n in range(radii.size)]
303+
angles += angles[:1]
304+
305+
if ax is None:
306+
# Initialise the spider plot
307+
fig = plt.figure(figsize=(8, 8))
308+
ax = fig.add_subplot(111, polar=True)
309+
# If you want the first axis to be on top:
310+
ax.set_theta_offset(pi / 2)
311+
ax.set_theta_direction(-1)
312+
# Draw one axe per variable + add labels
313+
plt.xticks(angles[:-1], labels)
314+
# Draw ylabels
315+
ax.set_rlabel_position(0)
316+
if ylim is None:
317+
ylim = (0, np.max(radii))
318+
if ticks is None:
319+
ticks = np.linspace(ylim[0], ylim[1], 5)
320+
plt.yticks(ticks, [f'{t:2.2f}' for t in ticks], color="grey", size=7)
321+
plt.ylim(ylim)
322+
323+
r = np.r_[radii, radii[0]]
324+
p = ax.plot(angles, r, linewidth=1, linestyle='solid', label="group A", color=color)
325+
ax.fill(angles, r, alpha=0.1, color=p[0].get_color())
326+
if title is not None:
327+
ax.set_title(title)
328+
return ax

ibllib/tests/test_plots.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1-
import unittest
1+
from pathlib import Path
22
import tempfile
3+
import unittest
34
import uuid
45

5-
from pathlib import Path
6+
import matplotlib.pyplot as plt
7+
import numpy as np
68
from PIL import Image
79
from urllib.parse import urlparse
810

911
from one.api import ONE
1012
from one.webclient import http_download_file
1113

14+
import ibllib.plots.misc
1215
from ibllib.tests import TEST_DB
1316
from ibllib.tests.fixtures.utils import register_new_session
1417
from ibllib.plots.snapshot import Snapshot
1518
from ibllib.plots.figures import dlc_qc_plot
1619

20+
1721
WIDTH, HEIGHT = 1000, 100
1822

1923

@@ -163,3 +167,19 @@ def test_without_inputs(self):
163167
# fig.savefig(fig_path)
164168
# with Image.open(fig_path) as im:
165169
# self.assertEqual(im.size, (1700, 1000))
170+
171+
172+
class TestMiscPlot(unittest.TestCase):
173+
174+
def test_star_plot(self):
175+
r = np.random.rand(6)
176+
ax = ibllib.plots.misc.starplot(['a', 'b', 'c', 'd', 'e', 'f'], r, ylim=[0, 1])
177+
r = np.random.rand(6)
178+
ibllib.plots.misc.starplot(['a', 'b', 'c', 'd', 'e', 'f'], r, ax=ax, color='r')
179+
plt.close('all')
180+
181+
def test_wiggle(self):
182+
w = np.random.rand(500, 40) - 0.5
183+
ibllib.plots.misc.wiggle(w, fs=30000)
184+
ibllib.plots.misc.Traces(w, fs=30000, color='r')
185+
plt.close('all')

0 commit comments

Comments
 (0)