Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plot points and rectangles in Ruby

Tags:

plot

ruby

svg

I am searching for an easy way to plot about 10 points and rectangles to be able to see where my algorithm goes wrong. I had a look at gnuplot, but it seems it is particularly bad a plotting rectangles.

like image 345
FlyingFoX Avatar asked Apr 25 '12 16:04

FlyingFoX


2 Answers

SVG (MDN Tutorial) is a very simple text-based (XML) format that you can emit easily using Ruby without any SVG library and view in any modern web browser. Here's one example:

SVG Points via String Interpolation

points = (0..5).map{ [rand(100)-50,rand(100)-50] }

puts <<ENDSVG
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-100 -100 200 200">
#{points.map{ |x,y| "<circle cx='#{x}' cy='#{y}' r='3' />" }.join("\n")}
</svg>
ENDSVG

Output: http://jsfiddle.net/xwnVY/


If you want to be more structured than string interpolation:

SVG Points Using Nokogiri XML Builder

require 'nokogiri' # gem install nokogiri
b = Nokogiri::XML::Builder.new do |doc|
  doc.svg xmlns:"http://www.w3.org/2000/svg", viewBox:"-100 -100 200 200" do
    points.each do |x,y|
      doc.circle r:3, cx:x, cy:y
    end
  end
end
puts b.to_xml

Save the output as "foo.svg" and open it in a modern web browser to view.


Drawing Rects

To draw rects, you can use any of:

<rect transform="rotate(45)" x="0" y="0" width="100" height="200" />
<polygon points="0,0 100,0 100,100 0,100" />
<path d="M0,0 L100,0 100,100 0,100 Z" />

The polygon may be the easiest to produce if you want to connect arbitrary points that are not axis-aligned without worrying about transforms. Note that while I've shown the coordinates above in the format x,y x,y for clarity, SVG will also accept x,y,x,y or x y x y, if those are easier for your code to generate.


A Bit of Formatting

If you want to draw outlines instead of filled shapes, you can add this CSS in your SVG:

<style>
  rect, polygon, path { fill:none; stroke:black; stroke-width:1px }
</style>

Using Haml for the XML

Finally, Haml is another option that you might consider for making your XML without an SVG-specific library:

@points = (0..7).map{ [rand(100)-50,rand(100)-50] }

require 'haml'
puts Haml::Engine.new(<<ENDHAML).render(self)
%svg(xmlns="http://www.w3.org/2000/svg" viewBox="-100 -100 200 200")
  :css
    circle { fill:orange }
    rect, polygon, path {
      fill:none; stroke:black;
      vector-effect:non-scaling-stroke
    }
  - @points.each_slice(4) do |rect|
    %polygon{ points:rect.join(" ") }
  - @points.each do |x,y|
    %circle{r:3, cx:x, cy:y}
ENDHAML

Output: http://jsfiddle.net/xwnVY/4/

like image 110
Phrogz Avatar answered Oct 16 '22 10:10

Phrogz


Perhaps you can try SVG. Easy to create (plain XML), open, cross-platform, you can open it and edit using Inkscape etc.

  • http://www.w3schools.com/svg/default.asp
  • https://developer.mozilla.org/en/SVG/Tutorial
  • http://www.svgbasics.com/
  • http://www.carto.net/svg/samples/
like image 5
Mladen Jablanović Avatar answered Oct 16 '22 11:10

Mladen Jablanović