Skip to content

Commit 15ddd34

Browse files
Merge pull request #791 from Nikoleta-v3/ax_to_plot
Additions to Plots
2 parents ac46d0f + f050d88 commit 15ddd34

File tree

4 files changed

+63
-35
lines changed

4 files changed

+63
-35
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ install:
1515
- pip install -r requirements.txt
1616
- pip install sphinx
1717
- pip install sphinx_rtd_theme
18+
- pip install docutils==0.12
1819
- pip install coverage
1920
- pip install coveralls
2021
script:

axelrod/plot.py

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,32 @@ def default_cmap():
2828

2929

3030
class Plot(object):
31-
3231
def __init__(self, result_set):
3332
self.result_set = result_set
3433
self.matplotlib_installed = matplotlib_installed
34+
self.nplayers = self.result_set.nplayers
35+
self.players = self.result_set.players
3536

36-
def _violinplot(self, data, names, title=None):
37+
def _violinplot(self, data, names, title=None, ax=None):
3738
"""For making violinplots."""
3839
if not self.matplotlib_installed:
3940
return None
40-
nplayers = self.result_set.nplayers
41-
width = max(nplayers / 3, 12)
41+
42+
if ax is None:
43+
_, ax = plt.subplots()
44+
else:
45+
ax = ax
46+
47+
figure = ax.get_figure()
48+
width = max(self.nplayers / 3, 12)
4249
height = width / 2
43-
figure = plt.figure(figsize=(width, height))
4450
spacing = 4
45-
positions = spacing * arange(1, nplayers + 1, 1)
51+
positions = spacing * arange(1, self.nplayers + 1, 1)
52+
figure.set_size_inches(width, height)
4653
plt.violinplot(data, positions=positions, widths=spacing / 2,
4754
showmedians=True, showextrema=False)
4855
plt.xticks(positions, names, rotation=90)
49-
plt.xlim(0, spacing * (nplayers + 1))
56+
plt.xlim(0, spacing * (self.nplayers + 1))
5057
plt.tick_params(axis='both', which='both', labelsize=8)
5158
if title:
5259
plt.title(title)
@@ -68,33 +75,32 @@ def _boxplot_xticks_locations(self):
6875
def _boxplot_xticks_labels(self):
6976
return [str(n) for n in self.result_set.ranked_names]
7077

71-
def boxplot(self, title=None):
78+
def boxplot(self, title=None, ax=None):
7279
"""For the specific mean score boxplot."""
7380
data = self._boxplot_dataset
7481
names = self._boxplot_xticks_labels
75-
figure = self._violinplot(data, names, title=title)
82+
figure = self._violinplot(data, names, title=title, ax=ax)
7683
return figure
7784

7885
@property
7986
def _winplot_dataset(self):
8087
# Sort wins by median
8188
wins = self.result_set.wins
82-
players = self.result_set.players
8389
medians = map(median, wins)
8490
medians = sorted(
8591
[(m, i) for (i, m) in enumerate(medians)], reverse=True)
8692
# Reorder and grab names
8793
wins = [wins[x[-1]] for x in medians]
88-
ranked_names = [str(players[x[-1]]) for x in medians]
94+
ranked_names = [str(self.players[x[-1]]) for x in medians]
8995
return wins, ranked_names
9096

91-
def winplot(self, title=None):
97+
def winplot(self, title=None, ax=None):
9298
"""Plots the distributions for the number of wins for each strategy."""
9399
if not self.matplotlib_installed:
94100
return None
95101

96102
data, names = self._winplot_dataset
97-
figure = self._violinplot(data, names, title)
103+
figure = self._violinplot(data, names, title=title, ax=ax)
98104
# Expand ylim a bit
99105
maximum = max(max(w) for w in data)
100106
plt.ylim(-0.5, 0.5 + maximum)
@@ -108,17 +114,16 @@ def _sd_ordering(self):
108114
def _sdv_plot_dataset(self):
109115
ordering = self._sd_ordering
110116
diffs = self.result_set.score_diffs
111-
players = self.result_set.players
112117
# Reorder and grab names
113118
diffs = [diffs[i] for i in ordering]
114-
ranked_names = [str(players[i]) for i in ordering]
119+
ranked_names = [str(self.players[i]) for i in ordering]
115120
return diffs, ranked_names
116121

117-
def sdvplot(self, title=None):
122+
def sdvplot(self, title=None, ax=None):
118123
"""Score difference violinplots to visualize the distributions of how
119124
players attain their payoffs."""
120125
diffs, ranked_names = self._sdv_plot_dataset
121-
figure = self._violinplot(diffs, ranked_names, title)
126+
figure = self._violinplot(diffs, ranked_names, title=title, ax=ax)
122127
return figure
123128

124129
@property
@@ -128,15 +133,13 @@ def _lengthplot_dataset(self):
128133
for length in rep[playeri]] for playeri in
129134
self.result_set.ranking]
130135

131-
def lengthplot(self, title=None):
136+
def lengthplot(self, title=None, ax=None):
132137
"""For the specific match length boxplot."""
133138
data = self._lengthplot_dataset
134139
names = self._boxplot_xticks_labels
135-
figure = self._violinplot(data, names, title=title)
140+
figure = self._violinplot(data, names, title=title, ax=ax)
136141
return figure
137142

138-
# Payoff heatmaps
139-
140143
@property
141144
def _payoff_dataset(self):
142145
pm = self.result_set.payoff_matrix
@@ -156,17 +159,20 @@ def _pdplot_dataset(self):
156159
ranked_names = [str(players[i]) for i in ordering]
157160
return matrix, ranked_names
158161

159-
def _payoff_heatmap(self, data, names, title=None):
162+
def _payoff_heatmap(self, data, names, title=None, ax=None):
160163
"""Generic heatmap plot"""
161164
if not self.matplotlib_installed:
162165
return None
163166

164-
nplayers = self.result_set.nplayers
165-
width = max(nplayers / 4, 12)
167+
if ax is None:
168+
_, ax = plt.subplots()
169+
else:
170+
ax = ax
171+
172+
figure = ax.get_figure()
173+
width = max(self.nplayers / 4, 12)
166174
height = width
167-
figure, ax = plt.subplots()
168-
figure.set_figwidth(width)
169-
figure.set_figheight(height)
175+
figure.set_size_inches(width, height)
170176
cmap = default_cmap()
171177
mat = ax.matshow(data, cmap=cmap)
172178
plt.xticks(range(self.result_set.nplayers))
@@ -182,29 +188,33 @@ def _payoff_heatmap(self, data, names, title=None):
182188
plt.colorbar(mat, cax=cax)
183189
return figure
184190

185-
def pdplot(self, title=None):
191+
def pdplot(self, title=None, ax=None):
186192
"""Payoff difference heatmap to visualize the distributions of how
187193
players attain their payoffs."""
188194
matrix, names = self._pdplot_dataset
189-
return self._payoff_heatmap(matrix, names, title)
195+
return self._payoff_heatmap(matrix, names, title=title, ax=ax)
190196

191-
def payoff(self, title=None):
197+
def payoff(self, title=None, ax=None):
192198
"""Payoff heatmap to visualize the distributions of how
193199
players attain their payoffs."""
194200
data = self._payoff_dataset
195201
names = self.result_set.ranked_names
196-
return self._payoff_heatmap(data, names, title)
202+
return self._payoff_heatmap(data, names, title=title, ax=ax)
197203

198204
# Ecological Plot
199205

200-
def stackplot(self, eco, title=None, logscale=True):
201-
206+
def stackplot(self, eco, title=None, logscale=True, ax=None):
202207
if not self.matplotlib_installed:
203208
return None
204209

205210
populations = eco.population_sizes
206211

207-
figure, ax = plt.subplots()
212+
if ax is None:
213+
_, ax = plt.subplots()
214+
else:
215+
ax = ax
216+
217+
figure = ax.get_figure()
208218
turns = range(len(populations))
209219
pops = [[populations[iturn][ir] for iturn in turns] for ir in self.result_set.ranking]
210220
ax.stackplot(turns, *pops)
@@ -225,7 +235,7 @@ def stackplot(self, eco, title=None, logscale=True):
225235
x = -0.01
226236
y = (i + 0.5) * 1.0 / self.result_set.nplayers
227237
ax.annotate(n, xy=(x, y), xycoords=trans, clip_on=False,
228-
va='center', ha='right', fontsize=5)
238+
va='center', ha='right', fontsize=5)
229239
ticks.append(y)
230240
ax.set_yticks(ticks)
231241
ax.tick_params(direction='out')
Loading

docs/tutorials/getting_started/visualising_results.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,20 @@ Saving all plots
5959

6060
The `axelrod.Plot` class has a method: `save_all_plots` that will save all the
6161
above plots to file.
62+
63+
Passing various objects to plot
64+
-------------------------------
65+
66+
The library give access to underlying matplotlib axes objects of each plot, thus
67+
the user can easily modify various aspects of a plot::
68+
69+
>>> import matplotlib.pyplot as plt
70+
>>> _, ax = plt.subplots()
71+
>>> title = ax.set_title('Payoff')
72+
>>> xlabel = ax.set_xlabel('Strategies')
73+
>>> p = plot.boxplot(ax=ax)
74+
>>> p.show()
75+
76+
.. image:: _static/visualising_results/title_labels_payoff.png
77+
:width: 50%
78+
:align: center

0 commit comments

Comments
 (0)