## DEV Community # "Valentine's Day Equation" plotted in Ruby

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.

``````# on Mac
brew install gnuplot
gem install gnuplot

# Chocolotey has a package for Windows
# choco install gnuplot

# Use rpm / apt on Linux
# apt-get install gnuplot
``````

## 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 variaous 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
``````

## 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

PDF we generated above is perfect for printing, but if you wanted to convert it to an 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
``````