Cat Paw Chart aka Bubble plot — Pyplot and Descartes circles

wu am i
3 min readApr 27, 2020

--

COVID Data Science has caught up with every one and I too was trying to visualize in different ways. Sample
here https://twitter.com/sivakd/status/1254638796177432577 . When I wanted to try bubble chart like the one in Tableau
I didn’t find any readily available. Then I tried to draw on and quickly realized that it’s not that simple unless one is familiar with Descartes or Apollonian Gaskets

Using Descartes — Calculate co-ordinates of 3rd circle given radii of 2 tangential circles using 3 radii
From https://lsandig.org/blog/2014/08/apollon-python/en/#descartes-and-his-disciples

#Using Descartes - Calculate co-ordinates of 3rd circle given radii of 2 tangential circles using 3 radii
def calculate_xy(r1,r2,r3):
x = (r1*r1+r1*r3+r1*r2-r2*r3)/(r1+r2)
y = math.sqrt((r1+r3)*(r1+r3)-x*x)
return x,y

We calculate child3 the x,y co-ordinates of tangential circle about the origin, so need to rotate about the same as child2

#From Stackoverflow
def rotate(point, origin=(0, 0), angle=0):
“””
Rotate a point counterclockwise by a given angle around a given origin.
The angle should be given in radians.
“””
ox, oy = origin
px, py = point
qx = ox + math.cos(angle) * (px — ox) — math.sin(angle) * (py — oy)
qy = oy + math.sin(angle) * (px — ox) + math.cos(angle) * (py — oy)
return qx, qy

We need angle between so that we rotate appropriately

#From Stackoverflow
def angle_between(p1, p2):
ang1 = np.arctan2(*p1[::-1])
ang2 = np.arctan2(*p2[::-1])
return np.rad2deg((ang1 — ang2) % (2 * np.pi))

Main plot
First we draw mother, child1 about the origin and y=0, just makes calculations easier child2 we use Descartes calculate_xy, no rotation as it is the first one child3 and on wards, we use calculate_xy and have to rotate about the angle of adjutant child(2) that’s it. Rest are for visual appeals

#Main plotfig, ax = plt.subplots(figsize=(10, 10))#start with 10,6, 4
d0=10
#from the origin 0,1,
x=0
y=0
r1=d0/2
ax.add_patch(plt.Circle((x, y), r1, color=’#adc5de’, clip_on=True,alpha=0.5))
ax.text(x, y, “Mother”, size=14, ha=’center’)
#Here we just use 3, 4, 5 ratios but can use actual ratio to mother r2=d0/3x=r1+r2
y=0
ax.add_patch(plt.Circle((x, y), r2, color=’#f7bb5f’, clip_on=True,alpha=0.5))
ax.text(x, y, “Child1”, size=14, ha=’center’)
#Here we just use 3, 4, 5 ratios but can use actual ratio to mother
r3=d0/4
#child2 just use Descartes
x,y=calculate_xy(r1,r2,r3)
ax.add_patch(plt.Circle((x, y), r3, color=’#deadbd’, clip_on=True,alpha=0.5))
ax.text(x, y, “Child2”, size=14, ha=’center’)
# — — — — — — — Descartes and rotate about origin — — — — — — ##here we calculate the x,y co-ordinates of child3 and also need to claculate the angle of roatation
r4=d0/5
deg = angle_between((x,y),(0,0))
x1,y1=calculate_xy(r1,r3,r4)
x,y = rotate((x1,y1),(0,0),angle=math.radians(deg))
ax.add_patch(plt.Circle((x, y), r4, color=’y’, clip_on=True,alpha=0.5))
ax.text(x, y, “Child3”, size=14, ha=’center’)
#here we calculate the x,y co-ordinates of child3 and also need to claculate the angle of roatation
r5=d0/6
deg = angle_between((x,y),(0,0))
x1,y1=calculate_xy(r1,r4,r5)
x,y = rotate((x1,y1),(0,0),angle=math.radians(deg))
ax.add_patch(plt.Circle((x, y), r5, color=’#2fb3af’, clip_on=True,alpha=0.5))
ax.text(x, y, “Child”, size=14, ha=’center’)
#ax.set_xticks([])
#ax.set_yticks([])
ax.set_xlim((-6, 12))
ax.set_ylim((-6, 12))
#Use adjustable=’datalim’ to make the plot area square-shaped as well.
ax.set_aspect(‘equal’, adjustable=’datalim’)
ax.plot()
plt.show()

That is it Enjoy! visit wu am i and https://www.ojaslabs.com

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

wu am i
wu am i

Written by wu am i

truth serum - pythonist, perpetual learner, ai/ml enthusiast, hope to build a personal robotic assistant (pra?) to take care me in my old age!

No responses yet

Write a response