
With the convening of the 2022 Beijing Winter Olympics, Bing DwenDwen and Shuey RhonRhon instantly jumped to “top traffic”. What if we can’t get it? Let’s write the code to create them!
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Ellipse
from matplotlib.patches import Rectangle
plt.rcParams['font.sans-serif']=['Comic Sans MS']
The basic idea of the code is actually very simple, that is to keep drawing ellipses. In order to simplify the code, we write a function to draw ellipses.
def ellipse(el, edgecolor='black', facecolor='w', n=0, alpha=1):
axs[n].add_patch(el)
el.set_facecolor(facecolor)
el.set_alpha(alpha)
el.set_edgecolor(edgecolor)
Bing DwenDwen 🐼
def BingDwenDwen():
# Ice shell
ellipse(Ellipse((0, -0.3), 6+0.3, 6.6+0.3, 0)) # Body
ellipse(Ellipse((1.7, 2.4), 1.2+0.3, 1.25+0.3, 0)) # Ear
ellipse(Ellipse((-1.7, 2.4), 1.2+0.3, 1.25+0.3, 0))
ellipse(Ellipse((-3, -0.9), 2.8+0.3, 1.2+0.3, 30)) # Left arm
ellipse(Ellipse((-3.7, -1.3), 1.16+0.3, 1.16+0.3, 0))
ellipse(Ellipse((-3, -0.9), 2.8+0.2, 1.2+0.2, 30),'w','w')
ellipse(Ellipse((3, 0.7), 2.8+0.3, 1.2+0.3, 45)) # Right arm
ellipse(Ellipse((3.6, 1.2), 1.16+0.3, 1.16+0.3, 0))
ellipse(Ellipse((3, 0.7), 2.8+0.2, 1.2+0.2, 45),'w','w')
ellipse(Ellipse((1.2, -3.2), 1.6+0.3, 2.4+0.3, 0)) # Right leg
ellipse(Ellipse((1.15, -4), 1.4+0.3, 1+0.3, 0))
ellipse(Ellipse((1.2, -3.2), 1.6+0.2, 2.4+0.2, 0), 'w', 'w')
ellipse(Ellipse((-1.2, -3.2), 1.6+0.3, 2.4+0.3, 0)) # Left leg
ellipse(Ellipse((-1.15, -4), 1.4+0.3, 1+0.3, 0))
ellipse(Ellipse((-1.2, -3.2), 1.6+0.2, 2.4+0.2, 0), 'w', 'w')
ellipse(Ellipse((0, -0.3), 6+0.2, 6.6+0.2, 0), 'w', 'w') # Body
# Ears
ellipse(Ellipse((1.7, 2.4), 1.2, 1.25, 0), 'black','black')
ellipse(Ellipse((-1.7, 2.4), 1.2, 1.25, 0), 'black','black')
# Arms
ellipse(Ellipse((-3, -0.9), 2.8, 1.2, 30), 'black','black') # Left
ellipse(Ellipse((-3.7, -1.3), 1.16, 1.16, 0), 'black','black')
ellipse(Ellipse((3, 0.7), 2.8, 1.2, 45), 'black','black') # Right
ellipse(Ellipse((3.6, 1.2), 1.16, 1.16, 0), 'black','black')
# Legs
ellipse(Ellipse((1.2, -3.2), 1.6, 2.4, 0), 'black','black')
ellipse(Ellipse((1.15, -4), 1.4, 1, 0), 'black','black')
ellipse(Ellipse((-1.2, -3.2), 1.6, 2.4, 0), 'black','black')
ellipse(Ellipse((-1.15, -4), 1.4, 1, 0), 'black','black')
# Body
ellipse(Ellipse((0, -0.3), 6, 6.6, 0), 'black')
# Rings around the face
for i in range(5):
width = 0.06
tt = np.linspace(0, np.pi, 100)
x1 = (2.45-width*i) * np.cos(tt)
y1 = (2.4-width*i) * np.sin(tt)
x2 = (2.45-width*i) * np.cos(tt)
y2 = -(1.7-width*i) * np.sin(tt)
axs[0].plot(x1,y1,color=colorList[i],linewidth=1)
axs[0].plot(x2,y2,color=colorList[i],linewidth=1)
# Eyes
ellipse(Ellipse((1.1, 1), 1, 1.4, 55), 'black','black') # Right
ellipse(Ellipse((0.9, 1), 0.5, 0.5, 0), 'w','black')
ellipse(Ellipse((1, 1), 0.05, 0.05, 0), 'w')
ellipse(Ellipse((-1.1, 1), 1, 1.4, -55), 'black','black') # Left
ellipse(Ellipse((-0.9, 1), 0.5, 0.5, 0), 'w','black')
ellipse(Ellipse((-0.8, 1), 0.05, 0.05, 0), 'w')
# Mouth
ellipse(Ellipse((0, -0.1), 1.2, 1, 20), 'black','black')
ellipse(Ellipse((0, 0.4), 0.8, 0.5, 10), 'w')
ellipse(Ellipse((0, -0.28), 0.85, 0.6, 10),'black', (180/255,39/255,45/255))
# Nose
ellipse(Ellipse((0, 0.5), 0.4, 0.2, 0), 'black','black')
# Olympic Rings
tt = np.linspace(0, 2*np.pi, 100)
x = 0.2*np.sin(tt)
y = 0.2*np.cos(tt) - 3.2
axs[0].plot(x-0.5,y+0.15,color=colorList[0],linewidth=0.65)
axs[0].plot(x-0.25,y,color=colorList[1],linewidth=0.65)
axs[0].plot(x,y+0.15,color=colorList[2],linewidth=0.65)
axs[0].plot(x+0.25,y,color=colorList[3],linewidth=0.65)
axs[0].plot(x+0.5,y+0.15,color=colorList[4],linewidth=0.65)
# Heart❤️ in the left hand
tt=np.linspace(-2.9,2.9,1000)
x=0.3*(np.sin(tt))**3
y=0.2*(1.3*np.cos(tt)-.5*np.cos(2*tt)-.2*np.cos(3*tt)-.1*np.cos(4*tt))
axs[0].fill(x+3.6, y+1.2, color=(180/255,39/255,45/255))
# LOGO
axs[0].text(0, -2.75, 'BEIJING 2022', ha='center', fontsize=5)

Shuey RhonRhon 🏮
def ShueyRhonRhon():
gold = (255/255, 215/255, 0) # The main body of Shuey RhonRhon is composed of red and gold, and the commonly used RGB value of gold is (255, 215, 0)
# Arms
ellipse(Ellipse((-1.4, -2.5), 1.65, 0.65, -30), 'r', 'r', 1)
ellipse(Ellipse((1.45, -2.9), 1.6, 0.6, -40), 'r', 'r', 1)
# Head
ellipse(Ellipse((0, 2), 4.3, 1.7, 0), 'r', 'r', 1)
ellipse(Ellipse((0, 0), 6.2, 4.8, 0), 'r', 'r', 1)
ellipse(Ellipse((0, 0), 4.6, 5, 0), gold, 'r', 1)
ellipse(Ellipse((0, 0), 2.6, 5, 0), gold, 'r', 1)
ellipse(Ellipse((0, 0), 0.01, 5, 0), gold, 'r', 1)
ellipse(Ellipse((0, 0), 3.5, 1.8, 0), 'w', 'w', 1)
ellipse(Ellipse((-1.2, -0.5), 1.4, 1, 0), 'w', 'w', 1)
ellipse(Ellipse((-0.6, 0.6), 1.5, 1, 0), 'w', 'w', 1)
ellipse(Ellipse((0, 0.8), 1.5, 1, 0), 'w', 'w', 1)
ellipse(Ellipse((-1.35, -0.68), 0.65, 0.6, 0), 'w', 'w', 1)
ellipse(Ellipse((1.4, -0.5), 1, 0.8, 160), 'w', 'w', 1)
# Outline
tt = np.linspace(np.pi/2, np.pi/2*3, 100)
x = 3.25 * np.sin(tt)
y = 2.5 * np.cos(tt) + 0.1
axs[1].plot(x, y, color='w', linewidth=1)
tt = np.linspace(-np.pi/3, np.pi/3, 100)
x = 3.3 * np.sin(tt)
y = 2.5 * np.cos(tt) + 0.21
axs[1].plot(x, y, color='w', linewidth=5)
# Eyes and blush
ellipse(Ellipse((1, 0), 0.2, 0.3, 0), 'black', 'black', 1)
ellipse(Ellipse((-1, 0), 0.2, 0.3, 0), 'black', 'black', 1)
ellipse(Ellipse((1, 0.1), 0.02, 0.02, 0), 'w', 'w', 1)
ellipse(Ellipse((-1, 0.1), 0.02, 0.02, 0), 'w', 'w', 1)
ellipse(Ellipse((1.4, -0.45), 0.5, 0.4, 0), 'w', 'r', 1, 0.4)
ellipse(Ellipse((-1.4, -0.45), 0.5, 0.4, 0), 'w', 'r', 1, 0.4)
# Legs
ellipse(Ellipse((0.66, -4), 0.6, 0.8, 0), 'r', 'r', 1)
ellipse(Ellipse((0.56, -4.2), 0.8, 0.6, 0), 'r', 'r', 1)
ellipse(Ellipse((-0.66, -4), 0.6, 0.8, 0), 'r', 'r', 1)
ellipse(Ellipse((-0.56, -4.2), 0.8, 0.6, 0), 'r', 'r', 1)
# Body
ellipse(Ellipse((0, -3.25), 2.6, 1.9, 0), 'r', 'r', 1)
ellipse(Ellipse((0, -3.25), 1.15, 1.15, 0), 'w', 'w', 1)
ellipse(Ellipse((0, -3.25), 1.25, 1.25, 0), gold, gold, 1, 0.5)
ellipse(Ellipse((0, -3.25), 1, 1, 0), 'w', 'w', 1)
# Scarf
tt = np.linspace(np.pi-0.35, np.pi+0.36, 100)
x = 3.25 * np.sin(tt)
y = 2.55 * np.cos(tt) + 0.1
axs[1].plot(x, y-0.02, color='black', linewidth=5)
axs[1].plot(x, y, color=gold, linewidth=5)
axs[1].add_patch(Rectangle((-1+0.02,-3.1-0.02),0.6,0.05,70,color='black'))
axs[1].add_patch(Rectangle((-1.15+0.02,-3.045-0.02),0.25,0.05,70,color='black'))
axs[1].add_patch(Rectangle((-1.3+0.02,-2.985-0.02),0.25,0.05,70,color='black'))
axs[1].add_patch(Rectangle((-1.45+0.02,-2.925-0.02),0.25,0.05,70,color='black'))
axs[1].add_patch(Rectangle((-0.91,-2.85),0.4,0.54,70,color=gold))
axs[1].add_patch(Rectangle((-1,-3.1),0.25,0.05,70,color=gold))
axs[1].add_patch(Rectangle((-1.15,-3.045),0.25,0.05,70,color=gold))
axs[1].add_patch(Rectangle((-1.3,-2.985),0.25,0.05,70,color=gold))
axs[1].add_patch(Rectangle((-1.45,-2.925),0.25,0.05,70,color=gold))
# Pigeon🐦 motif on the headdress
def pigeon(x, y, sign=1):
ellipse(Ellipse((x, y), 0.1, 0.2, sign*45), gold, gold, 1)
ellipse(Ellipse((x+sign*0.1, y), 0.1, 0.2, -sign*45), gold, gold, 1)
ellipse(Ellipse((x+sign*0.22, y+0.1), 0.2, 0.08, sign*20), gold, gold, 1)
ellipse(Ellipse((x-sign*0.1, y+0.1), 0.1, 0.01, 0), gold, gold, 1)
ellipse(Ellipse((x+sign*0.12, y-0.08), 0.05, 0.01, 0), gold, gold, 1)
ellipse(Ellipse((x+sign*0.17, y-0.03), 0.05, 0.01, 0), gold, gold, 1)
axs[1].add_patch(Rectangle((-2.2, 1.65), 4.4, 0.4, 0, color='r'))
ellipse(Ellipse((-0.2, 2.4), 1.6, 0.8, 0), 'w', 'w', 1)
ellipse(Ellipse((-1.2, 2.35), 0.6, 1.6, 110), 'w', 'w', 1)
ellipse(Ellipse((1.2, 2.3), 0.7, 1.4, 80), 'w', 'w', 1)
pigeon(0.25, 1.76)
pigeon(-0.25, 1.76, -1)
pigeon(1.5, 1.76)
pigeon(1.05, 1.76, -1)
pigeon(-1.05, 1.76)
pigeon(-1.5, 1.76, -1)
# Overhead handles
tt1 = np.linspace(-np.pi/3.2, np.pi/3.2, 100)
tt2 = np.linspace(0, np.pi, 100)
axs[1].plot(0.4*np.sin(tt1), 0.4*np.cos(tt1)+2.9, color=gold, linewidth=1)
axs[1].plot(0.1*np.sin(tt2)+0.36, 0.1*np.cos(tt2)+3, color=gold, linewidth=1)
axs[1].plot(-0.1*np.sin(tt2)-0.36, 0.1*np.cos(tt2)+3, color=gold, linewidth=1)
# Tree-like decorations on the feet
def tree(x, y):
ellipse(Ellipse((x, y-0.05), 0.05, 0.2, 0), gold, gold, 1)
ellipse(Ellipse((x, y+0.1), 0.05, 0.1, 0), gold, gold, 1)
ellipse(Ellipse((x+0.1, y+0.07), 0.1, 0.1, 0), gold, gold, 1)
ellipse(Ellipse((x-0.1, y+0.07), 0.1, 0.1, 0), gold, gold, 1)
ellipse(Ellipse((x+0.2, y+0.02), 0.06, 0.06, 0), gold, gold, 1)
ellipse(Ellipse((x-0.2, y+0.02), 0.06, 0.06, 0), gold, gold, 1)
ellipse(Ellipse((x, y-0.15), 0.1, 0.01, 0), gold, gold, 1)
tree(0.25,-4.2)
tree(0.75,-4.2)
tree(-0.25,-4.2)
tree(-0.75,-4.2)
# LOGO
axs[1].text(0, -3.4, 'BEIJING 2022', ha='center', fontsize=2)

fig, axs = plt.subplots(1, 2, subplot_kw={"aspect": "equal"})
axs[0].axis([-5, 5, -5, 5])
axs[1].axis([-5, 5, -5, 5])
axs[0].axis('off')
axs[1].axis('off')
colorList=[(98/255,205/255,247/255),(251/255,184/255,77/255),'black',(132/255,199/255,114/255), (158/255,48/255,87/255),] # The colors of the Olympic Rings
BingDwenDwen()
ShueyRhonRhon()
plt.show()
