class SVG::Plot

Attributes

axcolor[RW]
axlabelfontsize[RW]
axlabelstrokewidth[RW]
axlinewidth[RW]
colors[RW]
labels[RW]
legendbgcolor[RW]
legendbgopacity[RW]
legendfgcolor[RW]
legendfontsize[RW]
legendheight[RW]
legendlinelen[RW]
legendpad[RW]
linestyles[RW]
linewidth[RW]
markernum[RW]
markers[RW]
markersize[RW]
maxx[RW]
maxy[RW]
minx[RW]
miny[RW]
opacities[RW]
padbottom[RW]
padleft[RW]
padright[RW]
padtop[RW]
ticksfontsize[RW]
tickslen[RW]
ticksnum[RW]
ticksstrokewidth[RW]
tickstextlen[RW]
title[RW]
titlefontsize[RW]
xlabel[RW]
xlabelformat[RW]
ylabel[RW]
ylabelformat[RW]

Public Class Methods

colors() click to toggle source
# File lib/plot2d.rb, line 13
def self.colors() 
  return @@colors 
end
linestyles() click to toggle source
# File lib/plot2d.rb, line 24
def self.linestyles
  return @@linestyles
end
mapxcoords(x,minx,maxx,w,padleft,padright,log) click to toggle source
# File lib/plot2d.rb, line 124
def self.mapxcoords(x,minx,maxx,w,padleft,padright,log)
  begin 
    x = log ? Math.log(x,10) : x 
  rescue 
    STDERR.puts "WARNING error execption Math.log(#{x},10)"
    x = -1.0/0.0
  end 
  xnew = padleft + ((x - minx)/((maxx-minx) + 1e-100))*(w-(padleft + padright))
end
mapycoords(y,miny,maxy,h,padtop,padbottom,log) click to toggle source
# File lib/plot2d.rb, line 134
def self.mapycoords(y,miny,maxy,h,padtop,padbottom,log)
  begin 
    y = log ? Math.log(y,10) : y 
  rescue 
    STDERR.puts "WARNING error execption Math.log(#{y},10)"
    y = -1.0/0.0
  end
  ynew = padtop + ((maxy - y)/((maxy-miny) + 1e-100))*(h-(padtop + padbottom))
end
markers() click to toggle source
# File lib/plot2d.rb, line 17
def self.markers() 
  return @@markers 
end
new(svg) click to toggle source
# File lib/plot2d.rb, line 42
def initialize(svg)
  @svg = svg

  @padleft   = 100
  @padright  = 50
  @padtop    = 50
  @padbottom = 100
  @colors    = [] 
  @labels    = []
  @markers   = [] 
  @linestyles   = [] 
  @opacities = [] 
  @linewidth = 2

  @markernum  = 10
  @markersize = 15
   
  @xlabel = ""
  @ylabel = ""
  @axcolor = "black"
  @axlinewidth = 2
  @axlabelstrokewidth = 0.5
  @axlabelfontsize = 25
  @xlabelformat = "%-0.4f"
  @ylabelformat = "%-0.4f"
   

  @ticksnum = 5
  @tickslen = 10 
  @tickstextlen = 60
  @ticksfontsize = 18
  @ticksstrokewidth = 0.1
  
  @legendfontsize = 20
  @legendbgcolor = "white"
  @legendbgopacity = 0.8
  @legendfgcolor = "black"
  @legendlinelen = 50 
  @legendheight = 100 
  @legendpad = 10 

  @title = ""
  @titlefontsize = 40 

  @minx = -1.0/0.0 
  @maxx = 1.0/0.0
  @miny = -1.0/0.0
  @maxy = 1.0/0.0

end

Public Instance Methods

axis(ticks,labels, flip: false, rotang: 0,**args) click to toggle source
# File lib/plot2d.rb, line 219
def axis(ticks,labels, flip: false, rotang: 0,**args)
  min,max = ticks[0], ticks[-1]
  # Dibujar el eje
  @svg.g(id: "axis#{flip ? @xlabel : @ylabel}", 
    text_anchor: "middle",
    stroke: @axcolor, 
    stroke_width: @axlinewidth,
    fill: @axcolor,**args) do |axis|
    axis.path() do |path|
      path.m(min[0],min[1])
      path.l(max[0],max[1])
    end 

    # Mostrar nombre
    t = SVG.transform do |t|
      if flip
        t.translate(@svg.width/2,@svg.height - @axlabelfontsize)
      else 
        t.translate(@axlabelfontsize,@svg.height/2)
        t.rotate(-90,0,0)
      end 
    end 

    axis.text(text: flip ? @xlabel : @ylabel, x: 0, y: 0, stroke_width: @axlabelstrokewidth,transform: t,
      font_size: @axlabelfontsize)

    # Colocar los ticks
    axis.path do |tickspath|
      (0 ... ticks.size).each do |i|
        x,y = ticks[i]
        tickspath.m(x-@tickslen/2,y)
        tickspath.l(@tickslen,0,relative: true)
        tickspath.m(x,y-@tickslen/2)
        tickspath.l(0,@tickslen,relative: true)
      end 
    end 

    # Colocar los valores
    (0 ... ticks.size).each do |i| 
      x,y = ticks[i]
      x +=  flip ? 0 : -@tickslen 
      y += !flip ? 0 : @tickslen + @ticksfontsize*1.5
      text = labels[i]
      axis.text(
        x: x, 
        y: y , 
        text: text, 
        text_anchor: flip ? "middle" : "end",
        stroke_width: @ticksstrokewidth,
        font_size: @ticksfontsize,
        transform: SVG.transform{|t| t.rotate(rotang,x,y)})
    end 
  end 
end
boxplot( boxesdata, colors: @@colors, markers: @@markers, linewidths: nil, labels: nil, opacity: nil, ylog: false, **args) click to toggle source
# File lib/plot2d/boxplot.rb, line 4
def boxplot(
    boxesdata,
    colors: @@colors,
    markers: @@markers,
    linewidths: nil,
    labels: nil,
    opacity: nil,
    ylog: false, **args)

  @colors = colors.dup
  @markers = markers.dup 
  @labels = labels.dup 
  linewidths = linewidths || @colors.size 

  #
  median = lambda do |arr|
    len = arr.size
    if arr.size.even? 
      return (arr[len/2] + arr[(len+1)/2])/2.0
    else 
      return arr[len/2]
    end
  end 

  mean = lambda do |arr|
    return arr.reduce(0.0){|acc,d| acc + d} / arr.size 
  end 

  std = lambda do |arr,mean|
    return (arr.reduce(0.0){|acc,d| acc + (d - mean)**2}/(arr.size-1))**0.5
  end 
 

  # Cantidad de cajas
  nboxes = boxesdata.size 
  min,max = boxesdata.flatten.minmax

  # Obtener los estadísticos necesarios para el boxplot
  boxes = [ ]
  nboxes.times do |i|
    box = {}
    data = boxesdata[i] 
  
    sz = data.size; 
    data = data.sort
    box[:mean] = mean.call(data)
    box[:q1] = median.call(data[0..data.size/2])
    box[:q2] = median.call(data) 
    box[:q3] = median.call(data[(data.size/2)+1..-1])
    box[:iqr] = box[:q3] - box[:q1]
    box[:median] = box[:q2]
    box[:std] = std.call(data,box[:mean])
  
    box[:w1] = data[0]
    (0 ... data.size).each do |i|
      if data[i]  >= (box[:q1] - (1.5*box[:iqr]))
        box[:w1] = data[i]
        break
      end 
    end 
    box[:w2] = data[-1]
    (0 ... data.size).reverse_each do |i|
      if data[i]  <= (box[:q3] + (1.5*box[:iqr]))
        box[:w2] = data[i]
        break
      end 
    end 

    boxes.push(box)
  end 

  # Modificar el máximo y mínimo para mostrar mejor los boxplots
  @maxy = boxes.map{|b| b[:w2]*1.01}.max 
  # @miny = boxes.map{|b| b[:w1]*0.1}.max

  boxscale = 0.5
  w = (@svg.width - (@padleft + @padright))  / nboxes
  boxes.each_with_index do |box,i|
    @svg.g(id: @labels.last,
      stroke: @colors[i], 
      fill: @colors[i],
      stroke_width: @linewidth,
      opacity: @opacities.last) do |g|

      boxwidth = boxscale * w
      x = @padleft + w*(i.to_f+0.5)

      ymedian = Plot.mapycoords(box[:median],@miny,@maxy,@svg.height,@padtop,@padbottom,ylog)

      # median line
      g.line(x1: x - boxwidth/2, y1: ymedian, x2: x + boxwidth/2, y2: ymedian, stroke: "black")

      # mean line
      ymean = Plot.mapycoords(box[:mean],@miny,@maxy,@svg.height,@padtop,@padbottom,ylog)
      g.line(
        x1: x - boxwidth/2, y1: ymean, 
        x2: x + boxwidth/2, y2: ymean, 
        stroke_dasharray: self.linestyle("--"),
        stroke: "black")

      # box
      yq3 = Plot.mapycoords(box[:q3],@miny,@maxy,@svg.height,@padtop,@padbottom,ylog)
      yq1 = Plot.mapycoords(box[:q1],@miny,@maxy,@svg.height,@padtop,@padbottom,ylog)

      g.rect(x: x-(boxwidth/2), y: yq3, width: boxwidth, height: (yq3-yq1).abs,opacity: 0.2)
      g.rect(x: x-(boxwidth/2), y: yq3, width: boxwidth, height: (yq3-yq1).abs,fill: "none", stroke: "black")
     
      # whiskers
      wisker_width = boxwidth/2
      w1 = Plot.mapycoords(box[:w1],@miny,@maxy,@svg.height,@padtop,@padbottom,ylog)
      w2 = Plot.mapycoords(box[:w2],@miny,@maxy,@svg.height,@padtop,@padbottom,ylog)
     
      g.path(stroke_dasharray: self.linestyle("-"),stroke: "black") do |wp|
        wp.m(x,w2)
        wp.m(-wisker_width/2,0,relative: true)
        wp.l(wisker_width,0,relative: true)
        wp.m(x,w2)
        wp.l(x,yq3)

        wp.m(x,w1)
        wp.m(-wisker_width/2,0,relative: true)
        wp.l(wisker_width,0,relative: true)
        wp.m(x,w1)
        wp.l(x,yq1)
      end  
      # Draw outliers
      boxesdata[i].each do |y| 
        next if  (y >= box[:w1] && y <= box[:w2])
        y = Plot.mapycoords(y,@miny,@maxy,@svg.height,@padtop,@padbottom,ylog)
        self.marker(@markers[i],x,y,"%g" % y,8)
      end  
     
    end 
  end 
  
end
boxplotticks(nboxes,boxscale = 0.5) click to toggle source
# File lib/plot2d.rb, line 290
def boxplotticks(nboxes,boxscale = 0.5)
  ticks = []
  labels = []

  w = (@svg.width - (@padleft + @padright)) / nboxes
  boxwidth = boxscale * w

  ticks.push([@padleft,@svg.height - @padbottom])
  labels.push("")
  nboxes.times do |i| 
    x =  @padleft + w*(i.to_f+0.5)
    ticks.push([x,@svg.height - @padbottom])
    labels.push("%d" % i)
  end 

  ticks.push([@svg.width - @padright,@svg.height - @padbottom])
  labels.push("")
  return ticks,labels
end
dark_mode() click to toggle source
# File lib/plot2d.rb, line 93
def dark_mode
  @axcolor = "white"
  @legendbgcolor = "black"
  @legendfgcolor = "white"
end
legend() click to toggle source
# File lib/plot2d.rb, line 175
def legend
  legendtextwidth = @legendfontsize*0.75*@labels.map{|e| e.size}.max
  legendwidth  = @legendlinelen + 3*@legendpad + legendtextwidth
  legendheight = 2*@legendpad + @labels.size*2*@legendfontsize

  t = SVG.transform do |t|
    t.translate(@svg.width-legendwidth-@padright,@padtop)
  end 

  @svg.g(id: "legend",transform: t) do |g|
    g.rect(
      x: 0, 
      y: 0 ,
      width: legendwidth, 
      height: legendheight, 
      stroke: "none" , 
      fill: @legendbgcolor, 
      opacity: @legendbgopacity)

    @labels.size.times do |i|
      y = @legendpad + @legendfontsize + (i*2*@legendfontsize)
      g.g(id: "legend-marker-line-"+@labels[i],fill: @colors[i],stroke: @colors[i]) do |g|
        g.line(
          x1: @legendpad,
          y1: y - @legendfontsize.to_i / 4, 
          x2: @legendpad+@legendlinelen, 
          y2: y - @legendfontsize.to_i / 4,
          stroke_dasharray: self.linestyle(@linestyles[i]))
        self.marker(
          @markers[i],
          @legendpad + @legendlinelen.to_i / 2,
          y - @legendfontsize.to_i / 4,
          "",
          @legendfontsize)
      end 
      g.text(x: @legendpad+@legendfontsize+@legendlinelen,y: y ,
        stroke: "none" ,
        fill: @legendfgcolor,
        text: @labels[i],
        font_size: @legendfontsize) 
    end 
  end 
end
linestyle(style) click to toggle source
# File lib/plot2d.rb, line 327
def linestyle(style)
  case style
  when "-" then "5 0"
  when "--","dashed" then "5"
  when "-.","dashdot" then "6 3 3 3"
  when ":","dotted"  then "2"
  when " ","","none" then "0 1"
  else style
  end 
end
map_and_zip(xraw,yraw,minx,maxx,miny,maxy,xlog,ylog) click to toggle source
# File lib/plot2d.rb, line 144
def map_and_zip(xraw,yraw,minx,maxx,miny,maxy,xlog,ylog)
  xp = xraw.map{|v| Plot.mapxcoords(v,minx,maxx,@svg.width,@padleft,@padright,xlog)}
  yp = yraw.map{|v| Plot.mapycoords(v,miny,maxy,@svg.height,@padtop,@padbottom,ylog)}
  pts = xp.zip(yp)  
  pts = pts.reject{|p| p[0].infinite? || p[1].infinite?}
  return pts
end
marker(marker,x,y,val,ms = @markersize) click to toggle source
# File lib/plot2d/markers.rb, line 3
def marker(marker,x,y,val,ms = @markersize)
  t = SVG.transform do |t|
    t.translate(x,y)
    t.scale(ms)
    case marker 
    when "D","x","X" then t.rotate(45)
    when ">","2","H" then t.rotate(90)
    when "v","3" then t.rotate(180)
    when "<","4" then t.rotate(270)
    else nil
    end 
  end 

  case marker 
  when "." then self.marker_point(t,val)
  when "," then self.marker_pixel(t,val)
  when "o" then self.marker_circle(t,val)
  when "^",">","v","<" then self.marker_triangle(t,val)
  when "s","D" then self.marker_square(t,val)
  when "d" then self.marker_diamond(t,val)
  when "+","x" then self.marker_plus(t,0.1,val)
  when "P","X" then self.marker_plus(t,0.2,val)
  when "1","2","3","4" then self.marker_tri(t,val)
  when "h","H" then self.marker_hexagon(t,val)
  when "p" then self.marker_pentagon(t,val)
  when "8" then self.marker_octagon(t,val)
  when "*" then self.marker_star(t,val)
  else raise "unkown marker #{marker}"
  end 
end
marker_circle(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 42
def marker_circle(t,val="")
  @svg.circle(cx: 0, cy: 0, r: 0.45, transform: t,title: val,stroke_width: 0)
end
marker_diamond(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 65
def marker_diamond(t,val="")
  @svg.path(transform: t, title: val,stroke_width: 0) do |path|
    path.m(0,-0.5)
    path.l(0.3,0)
    path.l(0,0.5)
    path.l(-0.3,0.0)
    path.z
  end 
end
marker_hexagon(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 123
def marker_hexagon(t,val="")
  @svg.path(title: val, transform: t,stroke_width: 0) do |path|
    path.m( 0.00,-0.50)
    path.l( 0.40,-0.20)
    path.l( 0.40, 0.30)
    path.l( 0.00, 0.50)
    path.l(-0.40, 0.30)
    path.l(-0.40,-0.20)
    path.z
  end 
end
marker_octagon(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 146
def marker_octagon(t,val="")
  @svg.path(title: val, transform: t,stroke_width: 0) do |path|
    path.m(-0.25,-0.50)
    path.l( 0.18,-0.50)
    path.l( 0.50,-0.25)
    path.l( 0.50, 0.18)
    path.l( 0.18, 0.50)
    path.l(-0.25, 0.50)
    path.l(-0.50, 0.18)
    path.l(-0.50,-0.25)
    path.z
  end 
end
marker_pentagon(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 135
def marker_pentagon(t,val="")
  @svg.path(title: val, transform: t,stroke_width: 0) do |path|
    path.m( 0.00,-0.50)
    path.l( 0.45,-0.10)
    path.l( 0.30, 0.50)
    path.l(-0.30, 0.50)
    path.l(-0.45,-0.10)
    path.z
  end 
end
marker_pixel(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 38
def marker_pixel(t,val="")
  @svg.circle(cx: 0, cy: 0, r: 0.2, transform: t,title: val,stroke_width: 0)
end
marker_plus(t,width,val="") click to toggle source
# File lib/plot2d/markers.rb, line 75
def marker_plus(t,width,val="")
  @svg.path(transform: t, title: val,stroke_width: 0 ) do |path|
    path.m(-width,-0.5)
    path.h(width)
    path.v(0.5)
    path.h(-width)
    path.z
  end 
  @svg.path(transform: t, title: val,stroke_width: 0 ) do |path|
    path.m(-0.5,-width)
    path.v(width)
    path.h(0.5)
    path.v(-width)
    path.z
  end 
end
marker_point(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 34
def marker_point(t,val="")
  @svg.circle(cx: 0, cy: 0, r: 0.3, transform: t,title: val,stroke_width: 0)
end
marker_square(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 55
def marker_square(t,val="")
  @svg.path(transform: t, title: val,stroke_width: 0) do |path|
    path.m(-0.4,-0.4)
    path.h(0.4)
    path.v(0.4)
    path.h(-0.4)
    path.z
  end 
end
marker_star(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 160
def marker_star(t,val="")
  @svg.path(title: val, transform: t,stroke_width: 0) do |path|
    path.m(0,-0.5)
    path.l(-0.3,0.5)
    path.l(0.5,-0.1)
    path.l(-0.5,-0.1)
    path.l(0.3,0.5)
    path.z
  end 
end
marker_tri(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 92
def marker_tri(t,val="")
  @svg.g(title: val, transform: t,stroke_width: 0) do |g|
    width = 0.1
    @svg.path(title: val) do |path|
      path.m(-width,0.5)
      path.h(width)
      path.v(0.0)
      path.h(-width)
      path.z
    end 
    @svg.path(
      title: val,
      transform: SVG.transform{|t| t.rotate(135)}) do |path|
      path.m(-width,0.5)
      path.h(width)
      path.v(0.0)
      path.h(-width)
      path.z
    end 
    @svg.path(
      title: val,
      transform: SVG.transform{|t| t.rotate(225)}) do |path|
      path.m(-width,0.5)
      path.h(width)
      path.v(0.0)
      path.h(-width)
      path.z
    end 
  end 
end
marker_triangle(t,val="") click to toggle source
# File lib/plot2d/markers.rb, line 46
def marker_triangle(t,val="")
  @svg.path(transform: t, title: val,stroke_width: 0) do |path|
    path.m(0,-0.5)
    path.l(0.5,0.5)
    path.l(-0.5,0.5)
    path.z
  end 
end
minmax(x,y,xlog: false,ylog: false) click to toggle source
# File lib/plot2d.rb, line 99
    def minmax(x,y,xlog: false,ylog: false)
      y = y.flatten 
      if ylog 
        y = y
          .map{|e|begin Math.log(e,10) rescue -1.0/0.0 end } 
          .reject{|e| e.infinite?} 
      end 

      miny,maxy = y.minmax
      @miny = miny unless (@miny && @miny.finite?)
      @maxy = maxy unless (@maxy && @maxy.finite?)

      x = x.flatten 
      if xlog 
        x = x
          .map{|e|begin Math.log(e,10) rescue -1.0/0.0 end } 
          .reject{|e| e.infinite?} 
      end 
      minx,maxx = x.minmax
      @minx = minx unless (@minx && @minx.finite?)
      @maxx = maxx unless (@maxx && @maxx.finite?)
    end 



    def self.mapxcoords(x,minx,maxx,w,padleft,padright,log)
      begin 
        x = log ? Math.log(x,10) : x 
      rescue 
        STDERR.puts "WARNING error execption Math.log(#{x},10)"
        x = -1.0/0.0
      end 
      xnew = padleft + ((x - minx)/((maxx-minx) + 1e-100))*(w-(padleft + padright))
    end 

    def self.mapycoords(y,miny,maxy,h,padtop,padbottom,log)
      begin 
        y = log ? Math.log(y,10) : y 
      rescue 
        STDERR.puts "WARNING error execption Math.log(#{y},10)"
        y = -1.0/0.0
      end
      ynew = padtop + ((maxy - y)/((maxy-miny) + 1e-100))*(h-(padtop + padbottom))
    end

    def map_and_zip(xraw,yraw,minx,maxx,miny,maxy,xlog,ylog)
      xp = xraw.map{|v| Plot.mapxcoords(v,minx,maxx,@svg.width,@padleft,@padright,xlog)}
      yp = yraw.map{|v| Plot.mapycoords(v,miny,maxy,@svg.height,@padtop,@padbottom,ylog)}
      pts = xp.zip(yp)  
      pts = pts.reject{|p| p[0].infinite? || p[1].infinite?}
      return pts
    end 

    def set_plot_style(label,color,marker,linestyle,opacity)
      label = @labels.size.to_s if !label
      color = @@colors[@labels.size] if  !color 
      marker = @@markers[@labels.size] if !marker
      linestyle = @@linestyles[@labels.size] if !linestyle
      opacity = 1.0 if !opacity

      @labels.push(label)
      @colors.push(color)
      @markers.push(marker)
      @linestyles.push(linestyle)
      @opacities.push(opacity)
    end 

    def title
      @svg.g(id: "title",text_anchor: "middle") do |g| 
        g.text(
          x: @svg.width / 2, y: @titlefontsize,
          text: @title,
          font_size: @titlefontsize)
      end 
    end 

    def legend
      legendtextwidth = @legendfontsize*0.75*@labels.map{|e| e.size}.max
      legendwidth  = @legendlinelen + 3*@legendpad + legendtextwidth
      legendheight = 2*@legendpad + @labels.size*2*@legendfontsize

      t = SVG.transform do |t|
        t.translate(@svg.width-legendwidth-@padright,@padtop)
      end 

      @svg.g(id: "legend",transform: t) do |g|
        g.rect(
          x: 0, 
          y: 0 ,
          width: legendwidth, 
          height: legendheight, 
          stroke: "none" , 
          fill: @legendbgcolor, 
          opacity: @legendbgopacity)

        @labels.size.times do |i|
          y = @legendpad + @legendfontsize + (i*2*@legendfontsize)
          g.g(id: "legend-marker-line-"+@labels[i],fill: @colors[i],stroke: @colors[i]) do |g|
            g.line(
              x1: @legendpad,
              y1: y - @legendfontsize.to_i / 4, 
              x2: @legendpad+@legendlinelen, 
              y2: y - @legendfontsize.to_i / 4,
              stroke_dasharray: self.linestyle(@linestyles[i]))
            self.marker(
              @markers[i],
              @legendpad + @legendlinelen.to_i / 2,
              y - @legendfontsize.to_i / 4,
              "",
              @legendfontsize)
          end 
          g.text(x: @legendpad+@legendfontsize+@legendlinelen,y: y ,
            stroke: "none" ,
            fill: @legendfgcolor,
            text: @labels[i],
            font_size: @legendfontsize) 
        end 
      end 
    end 

    def axis(ticks,labels, flip: false, rotang: 0,**args)
      min,max = ticks[0], ticks[-1]
      # Dibujar el eje
      @svg.g(id: "axis#{flip ? @xlabel : @ylabel}", 
        text_anchor: "middle",
        stroke: @axcolor, 
        stroke_width: @axlinewidth,
        fill: @axcolor,**args) do |axis|
        axis.path() do |path|
          path.m(min[0],min[1])
          path.l(max[0],max[1])
        end 

        # Mostrar nombre
        t = SVG.transform do |t|
          if flip
            t.translate(@svg.width/2,@svg.height - @axlabelfontsize)
          else 
            t.translate(@axlabelfontsize,@svg.height/2)
            t.rotate(-90,0,0)
          end 
        end 

        axis.text(text: flip ? @xlabel : @ylabel, x: 0, y: 0, stroke_width: @axlabelstrokewidth,transform: t,
          font_size: @axlabelfontsize)

        # Colocar los ticks
        axis.path do |tickspath|
          (0 ... ticks.size).each do |i|
            x,y = ticks[i]
            tickspath.m(x-@tickslen/2,y)
            tickspath.l(@tickslen,0,relative: true)
            tickspath.m(x,y-@tickslen/2)
            tickspath.l(0,@tickslen,relative: true)
          end 
        end 

        # Colocar los valores
        (0 ... ticks.size).each do |i| 
          x,y = ticks[i]
          x +=  flip ? 0 : -@tickslen 
          y += !flip ? 0 : @tickslen + @ticksfontsize*1.5
          text = labels[i]
          axis.text(
            x: x, 
            y: y , 
            text: text, 
            text_anchor: flip ? "middle" : "end",
            stroke_width: @ticksstrokewidth,
            font_size: @ticksfontsize,
            transform: SVG.transform{|t| t.rotate(rotang,x,y)})
        end 
      end 
    end

    def yticks(min: @miny,max: @maxy,frmt: @ylabelformat, ticksnum: @ticksnum)
      ticks = []
      labels = []

      ticks.push([@padleft,Plot.mapycoords(min,min,max,@svg.height,@padtop,@padbottom,false)])
      labels.push(frmt % min)
        ticksnum.times do |i|
          v = min + ((max - min) / (ticksnum+1)) * (i+1)
          ticks.push([@padleft,Plot.mapycoords(v,min,max,@svg.height,@padtop,@padbottom,false)])
          labels.push(frmt % v)
        end 
        ticks.push([@padleft,Plot.mapycoords(max,min,max,@svg.height,@padtop,@padbottom,false)])
        labels.push(frmt % max)
        return ticks,labels
    end 

    def boxplotticks(nboxes,boxscale = 0.5)
      ticks = []
      labels = []

      w = (@svg.width - (@padleft + @padright)) / nboxes
      boxwidth = boxscale * w

      ticks.push([@padleft,@svg.height - @padbottom])
      labels.push("")
      nboxes.times do |i| 
        x =  @padleft + w*(i.to_f+0.5)
        ticks.push([x,@svg.height - @padbottom])
        labels.push("%d" % i)
      end 

      ticks.push([@svg.width - @padright,@svg.height - @padbottom])
      labels.push("")
      return ticks,labels
    end 

    def xticks(min: @minx, max: @maxx, ticksnum: @ticksnum, frmt: @xlabelformat)
      ticks = []
      labels = []

      ticks.push([Plot.mapxcoords(min,min,max,@svg.height,@padleft,@padright,false),@svg.height-@padbottom])
      labels.push(frmt % min)
      ticksnum.times do |i|
        v = min + ((max - min) / (ticksnum+1)) * (i+1)
        ticks.push([Plot.mapxcoords(v,min,max,@svg.height,@padleft,@padright,false),@svg.height-@padbottom])
        labels.push(frmt % v)
      end 
      ticks.push([Plot.mapxcoords(max,min,max,@svg.height,@padleft,@padright,false),@svg.height-@padbottom])
      labels.push(frmt % max)
      return ticks,labels

    end 

    def linestyle(style)
      case style
      when "-" then "5 0"
      when "--","dashed" then "5"
      when "-.","dashdot" then "6 3 3 3"
      when ":","dotted"  then "2"
      when " ","","none" then "0 1"
      else style
      end 
    end 


  end 
end
plot( xraw, yraw, minx: @minx,maxx: @maxx,miny: @miny,maxy: @maxy, label: nil, color: nil, marker: nil, linestyle: nil, opacity: nil, xlog: false,ylog: false) click to toggle source
# File lib/plot2d/lineplot.rb, line 3
def plot(
  xraw, yraw,
  minx: @minx,maxx:  @maxx,miny:  @miny,maxy:  @maxy,
  label:  nil,
  color: nil,
  marker: nil,
  linestyle: nil,
  opacity:  nil,
  xlog: false,ylog: false)

  self.set_plot_style(label,color,marker,linestyle,opacity)
  points = self.map_and_zip(xraw,yraw,minx,maxx,miny,maxy,xlog,ylog)
  
  @svg.g(
    id: @labels.last,
    stroke: @colors.last, 
    fill: @colors.last, 
    stroke_width: @linewidth,
    opacity: @opacities.last) do |g|

      g.path(title: @labels.last,fill: "none",stroke_dasharray: self.linestyle(@linestyles.last)) do |path|
      missing = true
      points.each do |(x,y)|
        if !x.finite? || !y.finite?
          missing = true 
          next
        end 
        if missing 
          path.m(x,y)
          missing = false
        end 
        path.l(x,y) 
      end 
    end 
  
    g.g(id: @labels.last+"-markers", fill: @colors.last) do |mg| 
      points.each_with_index do |(x,y),i|
        next if ((i % (points.size.to_i / @markernum.to_i)) != 0) || !x.finite? || !y.finite?
        self.marker(@markers.last,x,y,yraw[i].round(2))
      end 
    end 
  end  

end
scatter( xraw, yraw, minx: @minx, maxx: @maxx, miny: @miny, maxy: @maxy, label: nil, color: nil, marker: nil, opacity: nil, xlog: false, ylog: false,**args) click to toggle source
# File lib/plot2d/scatter.rb, line 3
def scatter(
  xraw, yraw, 
  minx: @minx, maxx:  @maxx, miny: @miny, maxy: @maxy,
  label: nil, 
  color:  nil, 
  marker:  nil, 
  opacity:  nil,
  xlog: false, ylog: false,**args)
 
  self.set_plot_style(label,color,marker,"",opacity)
  points = self.map_and_zip(xraw,yraw,minx,maxx,miny,maxy,xlog,ylog)
 
  @svg.g(id: @labels.last, stroke: "none",fill: @colors.last,opacity: @opacities.last) do |g|
    points.each_with_index do |(x,y),i|
      self.marker(@markers.last,x,y,"%g" % yraw[i])
    end 
  end 

end
set_plot_style(label,color,marker,linestyle,opacity) click to toggle source
# File lib/plot2d.rb, line 152
def set_plot_style(label,color,marker,linestyle,opacity)
  label = @labels.size.to_s if !label
  color = @@colors[@labels.size] if  !color 
  marker = @@markers[@labels.size] if !marker
  linestyle = @@linestyles[@labels.size] if !linestyle
  opacity = 1.0 if !opacity

  @labels.push(label)
  @colors.push(color)
  @markers.push(marker)
  @linestyles.push(linestyle)
  @opacities.push(opacity)
end
xticks(min: @minx, max: @maxx, ticksnum: @ticksnum, frmt: @xlabelformat) click to toggle source
# File lib/plot2d.rb, line 310
def xticks(min: @minx, max: @maxx, ticksnum: @ticksnum, frmt: @xlabelformat)
  ticks = []
  labels = []

  ticks.push([Plot.mapxcoords(min,min,max,@svg.height,@padleft,@padright,false),@svg.height-@padbottom])
  labels.push(frmt % min)
  ticksnum.times do |i|
    v = min + ((max - min) / (ticksnum+1)) * (i+1)
    ticks.push([Plot.mapxcoords(v,min,max,@svg.height,@padleft,@padright,false),@svg.height-@padbottom])
    labels.push(frmt % v)
  end 
  ticks.push([Plot.mapxcoords(max,min,max,@svg.height,@padleft,@padright,false),@svg.height-@padbottom])
  labels.push(frmt % max)
  return ticks,labels

end
yticks(min: @miny,max: @maxy,frmt: @ylabelformat, ticksnum: @ticksnum) click to toggle source
# File lib/plot2d.rb, line 274
def yticks(min: @miny,max: @maxy,frmt: @ylabelformat, ticksnum: @ticksnum)
  ticks = []
  labels = []

  ticks.push([@padleft,Plot.mapycoords(min,min,max,@svg.height,@padtop,@padbottom,false)])
  labels.push(frmt % min)
    ticksnum.times do |i|
      v = min + ((max - min) / (ticksnum+1)) * (i+1)
      ticks.push([@padleft,Plot.mapycoords(v,min,max,@svg.height,@padtop,@padbottom,false)])
      labels.push(frmt % v)
    end 
    ticks.push([@padleft,Plot.mapycoords(max,min,max,@svg.height,@padtop,@padbottom,false)])
    labels.push(frmt % max)
    return ticks,labels
end