Last year, The New York Times published the article “The Perfect Valentine? A Math Formula” featuring a widget which allows you to visualise the equation
$(x^2 + (1+b)^2y^2 +z^2 -1)^3 -(x^2 +ay^2 )z^3 $
where both a and b are parameters. At first, this equation may not seem romantic at all. But as soon as we plot it we cannot help but agreeing with the article’s first sentence:
Nothing says I love you like an algebraic equation
You can customise your equation within the Süss — German for “sweet” — widget created for Valentine’s Day by Imaginary, a nonprofit organisation in Berlin that designs open-source mathematics programs and exhibitions. But if you are a true romantic, go ahead and make your very own 3D-heart (in your favourite colour palette) in Python using only numpy, pandas, and plotly. Code below ⬇️
Take a look at the interactive version (takes a bit to load!) in Chart Studio.
Python Code
# Author: @Quant_Girl
# Title: Perfect Valentine
# Type: 3d Scatter
import plotly.graph_objects as go
import numpy as np
import plotly.express as px
import pandas as pd
import chart_studio.plotly as py
def get_zvalue(a, b, x, y):
"""
Finds the roots of the polynomial in z
for given values of
a, b, x, y.
"""
constant = x ** 2 + ((1 + b) * y) ** 2 - 1
c0 = constant ** 3
c1 = 0.0
c2 = 3 * (constant ** 2)
c3 = -(a * (y ** 2) + x ** 2)
c4 = 3 * constant
c5 = 0.0
c6 = 1.0
coefficients = [c6, c5, c4, c3, c2, c1, c0]
rts = np.roots(coefficients)
z = rts[~np.iscomplex(rts)]
if len(z) > 0:
zreal = z.real
return zreal
else:
return []
def draw_heart(a=9/200, b=0.01, grid=0.10, palette='viridis'):
"""
Draws the figure
@param a: a>0
@param b:
@param grid: sparsity of the scatter
@param palette: palette
"""
x = np.arange(-2, 2, grid)
y = x
all_triplets = []
for i in x:
for j in y:
zaxis = get_zvalue(a, b, i, j)
for k in zaxis:
triplet = [i, j, k]
all_triplets.append(triplet)
results = np.array(all_triplets).transpose()
# Save the triplets in a data frame
xaxis = results[0]
yaxis = results[1]
zaxis = results[2]
df = pd.DataFrame({'x': xaxis, 'y': yaxis, 'z': zaxis})
# Draw
fig = go.Figure(data=px.scatter_3d(df, x='x', y='y', z='z',
color='z',
color_continuous_scale=palette,
height=800, width=800,
template="plotly_white"))
fig.update(layout_coloraxis_showscale=False)
fig.update_layout(
title='$\hbox{A Perfect Valentine: } (x^2 + (1+b)^2y^2 +z^2 -1)^3 -(x^2 +ay^2 )z^3$',
scene=dict(
xaxis=dict(showticklabels=False, showgrid=False),
yaxis=dict(showticklabels=False, showgrid=False),
zaxis=dict(showticklabels=False, showgrid=False),
bgcolor='white'))
fig.show()
draw_heart(palette='twilight')
Happy Valentine’s Day!