2

BACKGROUND

Per the Coastal Information Data Program (CDIP), they are generating a spectral heat/intensity map for wave swell at http://cdip.ucsd.edu/?nav=recent&sub=observed&units=metric&tz=UTC&pub=public&map_stati=1,2,3&stn=100&stream=p1&xitem=dir_spectrum.

This is dynamically generated with data containing energy density, duration (in seconds) & direction (in degrees with 180 degrees representing south).

DATA SAMPLE

Here's an explanation of the data: http://cdip.ucsd.edu/data_access/MEM_2dspectra.cdip

Here's a data sample for buoy 100 (same buoy as shown in the heat/intensity/spectral map: http://cdip.ucsd.edu/data_access/MEM_2dspectra.cdip?100

QUESTION

How do I take this 2-dimensional data and create a heat/intensity map ensuring that it is overlaid on Polar Coordinate map (and is the appropriate scale), just like the example url per CDIP's site?

Ultimately, I need this to be done in Ruby, preferably using ruby-gd or Rmagick, but I would greatly appreciate any language-agnostic solutions, too.

Chip Castle
  • 2,132
  • 3
  • 20
  • 34

2 Answers2

3

I am really in a rush, so can't finish right now, but as nobody answered yet, here is a first approach:

Code in Mathematica (sorry, as I said no time right now):

a = Import["http://cdip.ucsd.edu/data_access/MEM_2dspectra.cdip?100", 
   "Table"];

Graphics@Flatten[Table[

    (*colors, dont mind*)
    {ColorData["CMYKColors"][(a[[r, t]] - .000007)/(.0003 - 0.000007)], 

    (*point size, dont mind*)
    PointSize[1/Sqrt[r]/10], 

    (*Coordinates for your points "a" is your data matrix *)
       Point[
            {(rr =Log[.025 + (.58 - .25)/64 r]) Cos@(tt = t 5 Degree), 
              rr Sin@tt}]
            }

     (*values for the iteration*)
     , {r, 7, 64}, {t, 1, 72}], 1] 

     (*Rotation, dont mind*)
     /. gg : Graphics[___] :> Rotate[gg, Pi/2]  

I still can't get the right color scale:

enter image description here

Sjoerd C. de Vries
  • 16,122
  • 3
  • 42
  • 94
Dr. belisarius
  • 60,527
  • 15
  • 115
  • 190
  • Thanks for the quick example, but I have no experience with Mathematica (and not Matlab or gnuplot, either, as others have suggested to me). Would you be able to comment the code so I understand what it does? Thank you! – Chip Castle Mar 02 '11 at 16:13
  • @Chip yes, but not right now as I'm overflowing. It takes more time to explain that code than to write it. If you can wait, I'll come back to this one as soon as the work flood allows me. – Dr. belisarius Mar 02 '11 at 16:29
  • Or, if you are in a rush, you can post the code here under the `mathematica`tag and I am sure someone will come to rescue you. There is a nice mathematica community here. – Dr. belisarius Mar 02 '11 at 16:30
  • why the rotation by 90 degrees? what am I not seeing about the data? – rcollyer Mar 03 '11 at 05:10
  • @rcollyer The OP is trying to reproduce this Plot http://cdip.ucsd.edu/?nav=recent&sub=observed&units=metric&tz=UTC&pub=public&map_stati=1,2,3&stn=100&stream=p1&xitem=dir_spectrum as stated in the question. I managed to almost get there just guessing ... – Dr. belisarius Mar 03 '11 at 05:13
  • @rcollyer Beware the plot changes every day, mine is now history – Dr. belisarius Mar 03 '11 at 05:15
  • Looking closer at the example, it seems that zero degrees is +y with and its incremented clockwise, completely different than the usual practice. This means the Sin and Cos have to be interchanged. – rcollyer Mar 03 '11 at 05:18
  • @rcollyer Ops ... and now I saw the angles are measure clockwise. Those guys ought to be physicians. – Dr. belisarius Mar 03 '11 at 05:20
  • @rcollyer yep. Sin and Cos interchanged and rotated, the radius in an inverted scale, the center with a hole. They were definitively smoking something really good (**AND** the Log scale) – Dr. belisarius Mar 03 '11 at 05:22
  • @belisarius @rcollyer you guys clearly weren't boyscouts -- have you ever seen a compass: http://en.wikipedia.org/wiki/File:Compass_rose.png ? ;P) – Janus Mar 04 '11 at 05:12
  • @Janus Are those things renormalizable? – Dr. belisarius Mar 04 '11 at 05:20
  • @belisarius It looks like there's something missing in this code (after &@). – Sjoerd C. de Vries Jan 03 '12 at 21:20
  • @Sjoerd Nope. The &@ were not needed, probably a leftover of a previous version. BTW, did you see this one: http://stackoverflow.com/a/8694075/353410 – Dr. belisarius Jan 04 '12 at 01:15
2

Chip, I know, not using Ruby, but assuming that Belisarius's point calculation is fine, I'd use Mathematica's ListContourPlot instead, as it is much simpler to understand and it gives a cleaner picture.

(* Read in data, the web address can be specified *)
a = Import[<url of cpid data>, "Table"];

Import leaves in a pre tag in the first sublist and as a single element sublist at the end, this removes it

dat = a[[ ;; -2]][[All, -72;; ]];

by first taking all but the last element, and then taking the last 72 elements of each remaining sublists.

ListContourPlot expects a list of points of the form {{x, y, f}, ...}, so we need to transform dat into that form, as explained elsewhere:

pts =Flatten[
    Table[ {
          (rr =Log[.025 + (.58 - .25)/64 r]) Cos@(tt = t 5 Degree), (* x-coord *)
          rr Sin@tt, (* y-coord *)
          dat[[r,t]] (* function value *)
           },
           {r, 7, 64}, {t, 1, 72}
         ],
    1 ]

and then plot them

ListContourPlot[pts,
  ColorFunctionScaling -> False,
  ColorFunction -> (ColorData["CMYKColors"][(# - .000007)/(.0003 - 0.000007)]&)
  ]

This gives:

ListContourPlot of cpid data supplied by OP

which can be touched up by fixing the clipping and the ColorFunction scaling. Also, with some work radial contours could be added.

Community
  • 1
  • 1
rcollyer
  • 10,475
  • 4
  • 48
  • 75
  • +1 again ... but I can't. I never saw Import[ url, "Table"] .. is great. – Dr. belisarius Mar 03 '11 at 04:11
  • I knew mma could do it, and I originally tried it with `ReadList`, but alas it couldn't do it. Import, however ... The only catch was ensuring that it was imported correctly. – rcollyer Mar 03 '11 at 05:11
  • Really a pity the OP didn't bother to check your answer. Sometimes people ask questions just for the fun of it :( – Dr. belisarius Apr 24 '11 at 04:54