Skip to content

Commit 27a9bd4

Browse files
authored
Merge pull request #787 from theref/plotting
Add plotting option to Fingerprint plot
2 parents 1fa74da + 9bf7392 commit 27a9bd4

File tree

7 files changed

+90
-15
lines changed

7 files changed

+90
-15
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ target/
8181

8282
# Jupyter Notebook
8383
.ipynb_checkpoints
84-
84+
*.ipynb
8585
# pyenv
8686
.python-version
8787

axelrod/fingerprint.py

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,39 @@ def fingerprint(self, turns=50, repetitions=10, step=0.01, processes=None,
280280
self.data = self.generate_data(self.interactions, self.points, edges)
281281
return self.data
282282

283-
def plot(self, col_map='seismic', interpolation='none', title=None):
283+
@staticmethod
284+
def reshape_data(data, points, size):
285+
"""Shape the data so that it can be plotted easily.
286+
287+
Parameters
288+
----------
289+
data : dictionary
290+
A dictionary where the keys are Points of the form (x, y) and
291+
the values are the mean score for the corresponding interactions.
292+
293+
points : list
294+
of Point objects with coordinates (x, y).
295+
296+
size : int
297+
The number of Points in every row/column.
298+
299+
Returns
300+
----------
301+
plotting_data : list
302+
2-D numpy array of the scores, correctly shaped to ensure that the
303+
score corresponding to Point (0, 0) is in the left hand corner ie.
304+
the standard origin.
305+
"""
306+
ordered_data = [data[point] for point in points]
307+
shaped_data = np.reshape(ordered_data, (size, size), order='F')
308+
plotting_data = np.flipud(shaped_data)
309+
return plotting_data
310+
311+
def plot(self, col_map='seismic', interpolation='none', title=None, colorbar=True, labels=True):
284312
"""Plot the results of the spatial tournament.
285313
286314
Parameters
287315
----------
288-
filename : str, optional
289-
The location and name that the resulting plot should be saved to.
290-
Defaults to the current directory with the name
291-
`Strategy and Probe.pdf`
292316
col_map : str, optional
293317
A matplotlib colour map, full list can be found at
294318
http://matplotlib.org/examples/color/colormaps_reference.html
@@ -297,18 +321,36 @@ def plot(self, col_map='seismic', interpolation='none', title=None):
297321
http://matplotlib.org/examples/images_contours_and_fields/interpolation_methods.html
298322
title : str, optional
299323
A title for the plot
324+
colorbar : bool, optional
325+
Choose whether the colorbar should be included or not
326+
labels : bool, optional
327+
Choose whether the axis labels and ticks should be included
300328
301329
Returns
302330
----------
303331
figure : matplotlib figure
304332
A heat plot of the results of the spatial tournament
305333
"""
306334
size = int((1 / self.step) // 1) + 1
307-
ordered_data = [self.data[point] for point in self.points]
308-
plotting_data = np.reshape(ordered_data, (size, size))
309-
figure = plt.figure()
310-
plt.imshow(plotting_data, cmap=col_map, interpolation=interpolation)
311-
plt.axis('off')
335+
plotting_data = self.reshape_data(self.data, self.points, size)
336+
fig, ax = plt.subplots()
337+
cax = ax.imshow(plotting_data, cmap=col_map, interpolation=interpolation)
338+
339+
if colorbar:
340+
max_score = max(self.data.values())
341+
min_score = min(self.data.values())
342+
ticks = [min_score, (max_score + min_score) / 2, max_score]
343+
fig.colorbar(cax, ticks=ticks)
344+
345+
plt.xlabel('$x$')
346+
plt.ylabel('$y$', rotation=0)
347+
ax.tick_params(axis='both', which='both', length=0)
348+
plt.xticks([0, len(plotting_data) - 1], ['0', '1'])
349+
plt.yticks([0, len(plotting_data) - 1], ['1', '0'])
350+
351+
if not labels:
352+
plt.axis('off')
353+
312354
if title is not None:
313355
plt.title(title)
314-
return figure
356+
return fig

axelrod/tests/unit/test_fingerprint.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,33 @@ def test_generate_data(self):
160160
self.assertEqual(sorted(keys), self.expected_points)
161161
self.assertEqual(all(values), True)
162162

163+
def test_reshape_data(self):
164+
test_points = [Point(x=0.0, y=0.0),
165+
Point(x=0.0, y=0.5),
166+
Point(x=0.0, y=1.0),
167+
Point(x=0.5, y=0.0),
168+
Point(x=0.5, y=0.5),
169+
Point(x=0.5, y=1.0),
170+
Point(x=1.0, y=0.0),
171+
Point(x=1.0, y=0.5),
172+
Point(x=1.0, y=1.0)]
173+
test_data = {Point(x=0.0, y=0.0): 5,
174+
Point(x=0.0, y=0.5): 9,
175+
Point(x=0.0, y=1.0): 3,
176+
Point(x=0.5, y=0.0): 8,
177+
Point(x=0.5, y=0.5): 2,
178+
Point(x=0.5, y=1.0): 4,
179+
Point(x=1.0, y=0.0): 2,
180+
Point(x=1.0, y=0.5): 1,
181+
Point(x=1.0, y=1.0): 9}
182+
test_shaped_data = [[3, 4, 9],
183+
[9, 2, 1],
184+
[5, 8, 2]]
185+
af = AshlockFingerprint(self.strategy, self.probe)
186+
plotting_data = af.reshape_data(test_data, test_points, 3)
187+
for i in range(len(plotting_data)):
188+
self.assertEqual(list(plotting_data[i]), test_shaped_data[i])
189+
163190
def test_plot(self):
164191
af = AshlockFingerprint(self.strategy, self.probe)
165192
af.fingerprint(turns=10, repetitions=2, step=0.25, progress_bar=False)
@@ -170,7 +197,11 @@ def test_plot(self):
170197
r = af.plot(interpolation='bicubic')
171198
self.assertIsInstance(r, matplotlib.pyplot.Figure)
172199
t = af.plot(title='Title')
173-
self.assertIsInstance(r, matplotlib.pyplot.Figure)
200+
self.assertIsInstance(t, matplotlib.pyplot.Figure)
201+
u = af.plot(colorbar=False)
202+
self.assertIsInstance(u, matplotlib.pyplot.Figure)
203+
v = af.plot(labels=False)
204+
self.assertIsInstance(v, matplotlib.pyplot.Figure)
174205

175206
def test_wsls_fingerprint(self):
176207
axl.seed(0) # Fingerprinting is a random process
Loading
Loading
Loading

docs/tutorials/further_topics/fingerprinting.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ We get the plot:
5353
:width: 100%
5454
:align: center
5555

56-
We are also able to specify a matplotlib colour map and interpolation::
56+
We are also able to specify a matplotlib colour map, interpolation and can
57+
remove the colorbar and axis labels::
5758

58-
>>> af.plot(col_map='PuOr', interpolation='bicubic') # doctest: +SKIP
59+
>>> p = af.plot(col_map='PuOr', interpolation='bicubic', colorbar=False, labels=False) # doctest: +SKIP
60+
>>> p.show()
5961

6062
.. image:: _static/fingerprinting/WSLS_large_alt.png
6163
:width: 100%

0 commit comments

Comments
 (0)