def get_player_by_hero(self, hero, nameType=HeroIDType.NPC_NAME): if nameType != HeroIDType.NPC_NAME: convertName(hero, nameType, HeroIDType.NPC_NAME) try: return next(p for p in self.players if p.hero == hero) except StopIteration: print("Player with hero {} not found in replay {}.".format(hero, self.replayID)) return None
def x_label_icon(axis, y_pos=-0.15, size=1.0): x_axis = axis.get_xaxis() x_labels = x_axis.get_majorticklabels() x_locations = x_axis.get_major_locator() x_min, x_max = axis.get_xlim() x_range = x_max - x_min extra_artists = [] for label, x_loc in zip(x_labels, x_locations.locs): # This position wont work for some plots # x, _ = label.get_position() x = x_loc hero = label.get_text() try: # Get and resize the hero icon. icon = HeroIconPrefix / convertName(hero, HeroIDType.NPC_NAME, HeroIDType.ICON_FILENAME) except ValueError: print("Unable to find hero icon for: " + hero) continue x_rel = (float(x) - x_min)/x_range artist = make_image_annotation(icon, axis, x_rel, y_pos, size) extra_artists.append(artist) # Remove the old xlabels axis.set_xticklabels([]) return extra_artists
def plot_pick_context(picks: DataFrame, team, r_query, fig: Figure, summarise=False, limit=None): '''Plots the context (in picks and bans) of a teams top picks. Input is a DataFrame of picks, the TeamInfo and r_query context. ''' top_picks = picks.sum(axis=1).sort_values(ascending=False) fig.set_size_inches(8, 9) axes = fig.subplots(4, 5, sharey='row') extra_artists = [] def _do_plot(axis, colour, data): data.plot.bar(ax=axis, width=0.9, colormap=colour, grid=True, fontsize=8, sharey=True) extra_artists = x_label_icon(axis, y_pos=-0.15, size=0.5) axis.yaxis.set_major_locator(MaxNLocator(integer=True)) return extra_artists def _summarise(table, after: int): '''Assumes table is already sorted descending.''' other = table[after:].sum() table['Other'] = other table.sort_values(ascending=False, inplace=True) return table[:after + 1] for i_pick, pick in enumerate(top_picks[:5].index): nick = convertName(pick, HeroIDType.NPC_NAME, HeroIDType.NICK_NAME) axes[0, i_pick].set_title(nick) context = pick_context(pick, team, r_query, limit=limit) pick = context['Pick'].sort_values(ascending=False) pick = _summarise(pick, 5) if summarise else pick[:5] ban = context['Ban'].sort_values(ascending=False) ban = _summarise(ban, 5) if summarise else ban[:5] opick = context['Opponent Pick'].sort_values(ascending=False) opick = _summarise(opick, 5) if summarise else opick[:5] oban = context['Opponent Ban'].sort_values(ascending=False) oban = _summarise(oban, 5) if summarise else oban[:5] _do_plot(axes[0, i_pick], colour_list[0], pick) _do_plot(axes[1, i_pick], colour_list[1], ban) _do_plot(axes[2, i_pick], colour_list[2], opick) a4 = _do_plot(axes[3, i_pick], colour_list[3], oban) extra_artists += a4 axes[0, 0].set_ylabel('Pick', fontsize=14) axes[1, 0].set_ylabel('Ban', fontsize=14) axes[2, 0].set_ylabel('Opponent Pick', fontsize=14) axes[3, 0].set_ylabel('Opponent Ban', fontsize=14) return fig, axes, extra_artists
def hero_box_image(hero, isPick, isFirst=False, isWinner=False): # Get the template box. hero_box = pickban_box_image(isPick=isPick, isWinner=isWinner) # Get and resize the hero icon. icon_location = HeroIconPrefix / convertName(hero, HeroIDType.NPC_NAME, HeroIDType.ICON_FILENAME) icon = Image.open(icon_location) icon = icon.resize((64, 64)) # Paste the icon into the box hero_box.paste(icon, (0, 0), icon) # If its the first pick we want to highlight with a triangle. if isFirst: size = hero_box.size canvas = ImageDraw.Draw(hero_box) halfPoint = math.floor((size[1]-size[0])/2) spacing = 0 # Draws in the yellow triangle canvas.polygon([(1+spacing, size[0]+1+spacing), (halfPoint+spacing, size[0]+halfPoint+spacing), (1+spacing, size[1]-1+spacing)], fill='yellow') # Text text = "1st" font_size = size[1] - size[0] font = ImageFont.truetype('arialbd.ttf', font_size) outline_colour = (255, 255, 255, 255) w, h = font.getsize(text) x, y = (0,0) canvas.rectangle((x, y, x + w, y + h), fill='black') canvas.text((x, y), text, fill='white', font=font) return hero_box
def plot_pick_pairs(data: Dict[int, DataFrame], fig: Figure, num_heroes=10): '''Plots pick pair combinations for the DataFrame data. Heroes are replaced by icons. num_heroes determines the number of paris to consider. Returns axis and extra artists for extending bounding box. ''' nplots = max(data.keys()) + 1 fig.set_size_inches(8, 4*nplots) axes = fig.subplots(nplots) # Matplotlib will return a collection if nplots > 1, or a single object if 1 # So we just always make it a collection... Must be a better way. if nplots == 1: axes = (axes,) y_labels = ["First pair", "Second pair", "Third pair", "Fourth pair"] final_icon = [] for i, axis in zip(range(nplots), axes): working = data.get(i, Series(dtype='UInt16')) working = working[:num_heroes] if working.empty: axis.text(0.5, 0.5, "No Data", fontsize=14, horizontalalignment='center', verticalalignment='center') axis.yaxis.set_major_locator(MaxNLocator(integer=True)) continue working.plot.bar(ax=axis, width=0.9, grid=True) axis.set_ylabel(y_labels[i]) axis.yaxis.set_major_locator(MaxNLocator(integer=True)) hero_pairs = (h.split(', ') for h in working.index) x_axis = axis.get_xaxis() x_locations = x_axis.get_major_locator() x_min, x_max = axis.get_xlim() x_range = x_max - x_min for h_pair, x_loc in zip(hero_pairs, x_locations.locs): try: i1 = HeroIconPrefix / convertName(h_pair[0], HeroIDType.NPC_NAME, HeroIDType.ICON_FILENAME) except ValueError: print("Unable to find hero icon for: " + hero) continue try: i2 = HeroIconPrefix / convertName(h_pair[1], HeroIDType.NPC_NAME, HeroIDType.ICON_FILENAME) except ValueError: print("Unable to find hero icon for: " + hero) continue y_pos1 = -0.1 y_pos2 = -0.25 size = 1.0 x_rel = (float(x_loc) - x_min)/x_range make_image_annotation(i1, axis, x_rel, y_pos1, size) a2 = make_image_annotation(i2, axis, x_rel, y_pos2, size) # Should only need the bottom artist # final_icon = [a2, ] final_icon.append(a2) axis.set_xticklabels([]) axis.yaxis.set_major_locator(MaxNLocator(integer=True)) return fig, final_icon