TLDR: Use Ruby and GNUPlot to plot the mathematical Valentine’s Day heart equation. Perfect for teaching kids programming through something they relate to.
I’m trying to expose my kids to programming bit by bit. 😊 Things that work the best are something that they relate to. Almost right on cue, this blog post came up on my feed on dev.to on Saturday and I thought it would be a fun activity to help kids make Valentines in a new way. Thank you, @DevLorenz0 for the formula! ❤️
All you need is Ruby & GNUPlot, and possibly GNUPlot official docs PDF if you want to experiment further.
Installation
# on Mac
brew install gnuplot
gem install gnuplot
# Chocolatey has a package for Windows
# choco install gnuplot
# Use rpm / apt on Linux
# apt-get install gnuplot
The Code
# valentine_day_plot.rb
# Tested on Ruby 2.7.2
require 'rubygems'
require 'gnuplot'
valentines_day_function = lambda { |t|
x = 16 * Math.sin(t)**3
y = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t)
# Experimentally found that rounding to 4
# produces the best results for us
[x.round(4).to_f, y.round(4).to_f]
}
# Adjust this to get more or less number of plot points
# At the end we transpose array, to shape data for
# Gnuplot::DataSet input below
DISTANCE_BETWEEN_POINTS = 0.0001
COORDINATES = (0..(2 * Math::PI)).step(DISTANCE_BETWEEN_POINTS)
.to_a
.map do |t|
valentines_day_function.call(t)
end.transpose
Gnuplot.open do |gp|
Gnuplot::Plot.new(gp) do |plot|
plot.output 'valentine_day_plot.pdf'
# Sized as a nice square to be printed on a A4 or US Letter page
plot.terminal 'pdf colour size 8in,8in'
# The following is self-explanatory, but setting range too small,
# will put the graph out of bounds
plot.xrange '[-20:20]'
plot.yrange '[-20:20]'
plot.title "Valentine's Day Equation"
plot.ylabel 'Love-y'
plot.xlabel 'Love-x'
# DataSet.new can also take the formula directly, not just an array
# of shape [x-coordinates, y-coordinates]
plot.data << Gnuplot::DataSet.new(COORDINATES) do |ds|
# You can also draw graph using various other types,
# 'linespoints','steps','fillsteps', etc
# See http://www.gnuplot.info/docs_5.4/Gnuplot_5_4.pdf
# for full docs
ds.with = 'lines'
ds.linewidth = 15
# Change this to the name of your Valentine
ds.title = 'My Valentine'
end
end
end
The Result

Here is an example of the plotted graph if we change DISTANCE_BETWEEN_POINTS = 0.1 and ds.with = 'steps' and ds.linewidth = 1:

Bonus: Converting to Image Formats
The PDF we generated above is perfect for printing, but if you wanted to convert it to a JPEG or PNG, you can use a graphics app like Photoshop or GIMP, or simply use ImageMagick:
# Install it if you don't have it
brew install imagemagick
convert -quality 300 -density 300 valentine_day_plot.pdf valentine_day_plot.jpg
Resources
- Ruby Downloads
- GNUPlot Official Site
- GNUPlot Documentation PDF
- ImageMagick
- Original Valentine Equation Post by @DevLorenz0
Originally published: dev.to/konung/valentine-s-day-equation-plotted-in-ruby-6lo
Last updated: February 15, 2021