如何将Matplotlib中的标记替换为与线条同色的足球图标?
替换散点为同色足球图标解决方案
要把图表里的圆形散点换成和线条同色的足球图标,有两种简单的实现方式:
方法一:用足球Emoji快速搞定(无需额外资源)
直接用系统支持的足球emoji代替散点,代码改动最小,还能自动匹配线条颜色:
把你原代码里的plt.scatter()部分删掉,换成下面的代码:
# 获取客队线条的默认颜色 away_color = ax.lines[0].get_color() # 给每个客队进球点放足球emoji for x, y in zip(a_goal['minute'], a_goal['a_cum']): ax.text(x, y, '⚽', fontsize=14, color=away_color, ha='center', va='center') # 给每个主队进球点放红色足球emoji for x, y in zip(h_goal['minute'], h_goal['h_cum']): ax.text(x, y, '⚽', fontsize=14, color='red', ha='center', va='center')
完整代码如下:
import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(12,6)) ax.step(x = a_df['minute'], y = a_df['a_cum'], where = 'post', label= ateam, linewidth=2) ax.step(x = h_df['minute'], y = h_df['h_cum'], where = 'post', color ='red', label= hteam,linewidth=2) # 替换散点为足球emoji away_color = ax.lines[0].get_color() for x, y in zip(a_goal['minute'], a_goal['a_cum']): ax.text(x, y, '⚽', fontsize=14, color=away_color, ha='center', va='center') for x, y in zip(h_goal['minute'], h_goal['h_cum']): ax.text(x, y, '⚽', fontsize=14, color='red', ha='center', va='center') plt.xticks([0,15,30,45,60,75,90]) plt.yticks([0, 0.5, 1, 1.5, 2, 2.5, 3]) plt.grid() ax.title.set_text('The Expected Goals(xG) Chart Final Champions League 2010/2011') plt.ylabel("Expected Goals (xG)") plt.xlabel("Minutes") ax.legend() plt.show()
方法二:用自定义足球图片(更逼真)
如果想要更真实的足球样式,可以用一张透明背景的足球PNG图片,给图标染色后放到对应位置:
- 先准备一张透明背景的足球PNG(比如命名为
football.png) - 替换原代码的散点部分为以下代码:
import matplotlib.pyplot as plt from matplotlib.offsetbox import OffsetImage, AnnotationBbox from PIL import Image from matplotlib.colors import to_rgb fig, ax = plt.subplots(figsize=(12,6)) ax.step(x = a_df['minute'], y = a_df['a_cum'], where = 'post', label= ateam, linewidth=2) ax.step(x = h_df['minute'], y = h_df['h_cum'], where = 'post', color ='red', label= hteam,linewidth=2) # 定义给足球图标染色并添加到图表的函数 def add_colored_football(ax, x, y, img_path, target_color, zoom=0.05): # 加载透明背景的足球图片 img = Image.open(img_path).convert("RGBA") # 把图标颜色转为目标线条颜色 rgb_color = to_rgb(target_color) data = img.getdata() new_data = [] for r, g, b, alpha in data: if alpha > 0: # 替换颜色,保留透明度 new_data.append((int(rgb_color[0]*255), int(rgb_color[1]*255), int(rgb_color[2]*255), alpha)) else: new_data.append((r, g, b, alpha)) img.putdata(new_data) # 创建图标并定位到进球点 im = OffsetImage(img, zoom=zoom) ab = AnnotationBbox(im, (x, y), frameon=False, pad=0.0) ax.add_artist(ab) # 添加客队进球图标 away_color = ax.lines[0].get_color() for x, y in zip(a_goal['minute'], a_goal['a_cum']): add_colored_football(ax, x, y, "football.png", away_color) # 添加主队进球图标 for x, y in zip(h_goal['minute'], h_goal['h_cum']): add_colored_football(ax, x, y, "football.png", "red") plt.xticks([0,15,30,45,60,75,90]) plt.yticks([0, 0.5, 1, 1.5, 2, 2.5, 3]) plt.grid() ax.title.set_text('The Expected Goals(xG) Chart Final Champions League 2010/2011') plt.ylabel("Expected Goals (xG)") plt.xlabel("Minutes") ax.legend() plt.show()
内容的提问来源于stack exchange,提问作者Antonius Yoga Krisanto
相关产品推荐
相关产品推荐

