On Sun, Mar 9, 2008 at 2:15 AM, Alan W. Irwin <[EMAIL PROTECTED]> wrote:
>
> On 2008-03-08 23:48-0500 Hezekiah M. Carty wrote:
>
>  > In its current form, plimage automatically scales the plotted colors
>  > to take advantage of as much dynamic range in the color scale 1 as
>  > possible - the minimum value in the given image corresponds to a color
>  > of 0.0 and the maximum value in the image corresponds to a color of
>  > 1.0.
>  >
>  > The attached patch adds two extra parameters to plimage to allow a
>  > user to set this range on their own.  Image values of valuemin or less
>  > will now map to color 0.0 and image values of valuemax or greater will
>  > map to color 1.0.  Values between valuemin and valuemax will similarly
>  > map to colors between 0.0 and 1.0, in the same way plimage currently
>  > handles this.
>  >
>  > The reason for this change is to allow multiple plots to be made with
>  > varying data sets, while maintaining directly comparable color scales
>  > between plots.  The current implementation does not allow this for
>  > data sets with different value ranges without manually setting at
>  > least one pixel to a fixed minimum value and another to a fixed
>  > maximum value in each image.
>  >
>  > This patch affects include/plplot.h and src/plimage.c and should apply
>  > cleanly against the current PLplot Subversion head.  I have not made
>  > any adjustments to any of the included language bindings as I want to
>  > find out if this is an acceptable API change, if I should make this in
>  > to a new function instead.  I think it is a worthwhile adjustment to
>  > plimage, particularly given that it is an undocumented function,
>  > except for the code and an example.
>
>  The lack of plimage documentation is an oversight.  Thanks for pointing out
>  that issue.  I would encourage you to submit a patch for
>  doc/docbook/src/api.xml to add documentation for plimage (and also your
>  modified version of it, see next).
>
>  I think a variation of plimage with a user-specified colour range is worth
>  having, but to preserve backwards API compatibility you should rename your
>  modified version to something else and reimplement plimage as a wrapper so
>  it has the same arguments as now, derives the minimum and maximum of the
>  colour range, then calls plimagef to do the rest.  I would encourage you to
>  modify your present patch to that effect.

Thank you for your suggestions.  I have updated the patch as you suggested.

With this new patch, the updated plimage function is called plimager
("r" for "range").  plimage is, as you suggested Alan, a wrapper
around plimager using the min and max values from idata as valuemin
and valuemax.  It should act in the same way though - please let me
know if it does not.

Finally, I updated api.xml with these two functions.  I am unfamiliar
with DocBook so I copied and pasted another entry and used that as a
template.

I do not think that any bindings will have to be updated unless they
want to add plimager support since the plimage function signature has
not changed.

Please let me know what you think!

Hez

-- 
Hezekiah M. Carty
Graduate Research Assistant
University of Maryland
Department of Atmospheric and Oceanic Science
diff --git a/doc/docbook/src/api.xml b/doc/docbook/src/api.xml
index 4ccd6bb..b4461ad 100644
--- a/doc/docbook/src/api.xml
+++ b/doc/docbook/src/api.xml
@@ -5428,6 +5428,254 @@ device coordinates
 
   </sect1>
 
+  <sect1 id="plimager" renderas="sect3">
+    <title>
+        <function>plimager</function>: Plot a 2D matrix using color palette 1
+    </title>
+
+    <para>
+      <funcsynopsis>
+      <funcprototype>
+        <funcdef>
+           <function>plimager</function>
+        </funcdef>
+        <paramdef><parameter>idata</parameter></paramdef>
+        <paramdef><parameter>nx</parameter></paramdef>
+        <paramdef><parameter>ny</parameter></paramdef>
+        <paramdef><parameter>xmin</parameter></paramdef>
+        <paramdef><parameter>xmax</parameter></paramdef>
+        <paramdef><parameter>ymin</parameter></paramdef>
+        <paramdef><parameter>ymax</parameter></paramdef>
+        <paramdef><parameter>zmin</parameter></paramdef>
+        <paramdef><parameter>zmax</parameter></paramdef>
+        <paramdef><parameter>Dxmin</parameter></paramdef>
+        <paramdef><parameter>Dxmax</parameter></paramdef>
+        <paramdef><parameter>Dymin</parameter></paramdef>
+        <paramdef><parameter>Dymax</parameter></paramdef>
+        <paramdef><parameter>valuemin</parameter></paramdef>
+        <paramdef><parameter>valuemax</parameter></paramdef>
+      </funcprototype>
+      </funcsynopsis>
+    </para>
+
+    <para>
+      Plot a 2D matrix using color palette 1
+    </para>
+
+    <variablelist>
+      <varlistentry>
+	<term>
+	  <parameter>idata</parameter>
+	  (<literal>PLFLT**</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+              A 2D array of values (intensities) to plot.  Should have
+              dimensions idata[nx][ny].
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>nx, ny</parameter>
+	  (<literal>PLINT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+            Dimensions of idata
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>xmin, xmax, ymin, ymax</parameter>
+	  (<literal>PLFLT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+            Plot coordinates to strecth the image data to.  idata[0][0]
+            corresponds to (xmin, ymin) and idata[nx - 1][ny - 1] corresponds
+            to (xmax, ymax).
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>zmin, zmax</parameter>
+	  (<literal>PLFLT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+            Only data between zmin and zmax (inclusive) will be plotted.
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>Dxmin, Dxmax, Dymin, Dymax</parameter>
+	  (<literal>PLFLT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+              Plot only the window of points whose plot coordinates fall inside
+              the window of (Dxmin, Dymin) to (Dxmax, Dymax).
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>valuemin, valuemax</parameter>
+	  (<literal>PLFLT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+              The minimum and maximum data values to use for value to color
+              mappings.  A datum equal to or less than valuemin will be
+              plotted with color 0.0, while a datum equal to or greater than
+              valuemax will be plotted with color 1.0.  Data between valuemin
+              and valuemax map linearly to colors between 0.0 and 1.0.
+	  </para>
+	</listitem>
+      </varlistentry>
+
+    <para>
+      Redacted form: 
+      <itemizedlist>
+        <listitem>
+          <para>
+              General:
+              <function>
+                  plimager(idata, xmin, xmax, ymin, ymax,
+                  zmin, zmax, Dxmin, Dxmax, Dymin, Dymax,
+                  valuemin, valuemax)
+              </function>
+          </para>
+        </listitem>
+      </itemizedlist>
+    </para>
+
+    <para>
+      This function is not used in any examples.
+    </para>
+
+  </sect1>
+
+  <sect1 id="plimage" renderas="sect3">
+    <title>
+        <function>plimage</function>: Plot a 2D matrix using color palette 1
+    </title>
+
+    <para>
+      <funcsynopsis>
+      <funcprototype>
+        <funcdef>
+           <function>plimage</function>
+        </funcdef>
+        <paramdef><parameter>idata</parameter></paramdef>
+        <paramdef><parameter>nx</parameter></paramdef>
+        <paramdef><parameter>ny</parameter></paramdef>
+        <paramdef><parameter>xmin</parameter></paramdef>
+        <paramdef><parameter>xmax</parameter></paramdef>
+        <paramdef><parameter>ymin</parameter></paramdef>
+        <paramdef><parameter>ymax</parameter></paramdef>
+        <paramdef><parameter>zmin</parameter></paramdef>
+        <paramdef><parameter>zmax</parameter></paramdef>
+        <paramdef><parameter>Dxmin</parameter></paramdef>
+        <paramdef><parameter>Dxmax</parameter></paramdef>
+        <paramdef><parameter>Dymin</parameter></paramdef>
+        <paramdef><parameter>Dymax</parameter></paramdef>
+      </funcprototype>
+      </funcsynopsis>
+    </para>
+
+    <para>
+        Plot a 2D matrix using color palette 1.  The color scale is
+        automatically adjusted to use the maximum and minimum values in
+        idata as valuemin and valuemax in plimager.
+    </para>
+
+    <variablelist>
+      <varlistentry>
+	<term>
+	  <parameter>idata</parameter>
+	  (<literal>PLFLT**</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+              A 2D array of values (intensities) to plot.  Should have
+              dimensions idata[nx][ny].
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>nx, ny</parameter>
+	  (<literal>PLINT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+            Dimensions of idata
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>xmin, xmax, ymin, ymax</parameter>
+	  (<literal>PLFLT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+            Plot coordinates to strecth the image data to.  idata[0][0]
+            corresponds to (xmin, ymin) and idata[nx - 1][ny - 1] corresponds
+            to (xmax, ymax).
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>zmin, zmax</parameter>
+	  (<literal>PLFLT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+            Only data between zmin and zmax (inclusive) will be plotted.
+	  </para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term>
+	  <parameter>Dxmin, Dxmax, Dymin, Dymax</parameter>
+	  (<literal>PLFLT</literal>, input)
+	</term>
+	<listitem>
+	  <para>
+              Plot only the window of points whose plot coordinates fall inside
+              the window of (Dxmin, Dymin) to (Dxmax, Dymax).
+	  </para>
+	</listitem>
+      </varlistentry>
+
+    <para>
+      Redacted form: 
+      <itemizedlist>
+        <listitem>
+          <para>
+              General:
+              <function>
+                  plimager(idata, xmin, xmax, ymin, ymax,
+                  zmin, zmax, Dxmin, Dxmax, Dymin, Dymax)
+              </function>
+          </para>
+        </listitem>
+      </itemizedlist>
+    </para>
+
+    <para>
+      This function is used in example 20.
+    </para>
+
+  </sect1>
+
   <sect1 id="plinit" renderas="sect3">
     <title>
       <function>plinit</function>: Initialize PLplot
diff --git a/include/plplot.h b/include/plplot.h
index c6390d2..2ce82b5 100644
--- a/include/plplot.h
+++ b/include/plplot.h
@@ -1447,12 +1447,21 @@ c_plstripc(PLINT *id, const char *xspec, const char *yspec,
 PLDLLIMPEXP void
 c_plstripd(PLINT id);
 
-  /* plots a 2d image (or a matrix too large for plshade() ) */
+/* plots a 2d image (or a matrix too large for plshade() ) */
 
 PLDLLIMPEXP void
-plimage( PLFLT **data, PLINT nx, PLINT ny,
+plimager(PLFLT **idata, PLINT nx, PLINT ny,
 	 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
-	 PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax);
+	 PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax,
+         PLFLT valuemin, PLFLT valuemax);
+
+/* plots a 2d image (or a matrix too large for plshade() ) - colors
+   automatically scaled */
+
+PLDLLIMPEXP void
+plimage(PLFLT **idata, PLINT nx, PLINT ny,
+        PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
+        PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax);
 
 /* Set up a new line style */
 
diff --git a/src/plimage.c b/src/plimage.c
index 7bbd8ca..e13ced8 100644
--- a/src/plimage.c
+++ b/src/plimage.c
@@ -136,11 +136,10 @@ grimage(short *x, short *y, unsigned short *z, PLINT nx, PLINT ny)
 }
 
 /*-------------------------------------------------------------------------*\
- * plimage
- *           (***** SUBJECT TO CHANGE ******)
+ * plimager
  *
  * arguments are
- *   data: array containing image data
+ *   idata: array containing image data
  *   nx: dimension of the array in the X axis.
  *   ny: dimension of the  array in the Y axis
  *   The array data is indexed like data[ix][iy]
@@ -157,18 +156,36 @@ grimage(short *x, short *y, unsigned short *z, PLINT nx, PLINT ny)
  *       plots only the window of points whose(x,y)'s fall
  *       inside the [Dxmin->Dxmax]X[Dymin->Dymax] window
  *
+ *   valuemin, valuemax:
+ *       The minimum and maximum values to use for value -> color
+ *       mappings.  A value in idata of valuemin or less will have
+ *       color 0.0 and a value in idata of valuemax or greater will
+ *       have color 1.0.  Values between valuemin and valuemax will
+ *       map linearly to to the colors between 0.0 and 1.0.
+ *       If you do not want to display values outside of the
+ *       (valuemin -> valuemax) range, then set zmin = valuemin and
+ *       zmax = valuemax.
+ *       This allows for multiple plots to use the same color scale
+ *       with a consistent value -> color mapping, regardless of the
+ *       image content.
+ *
 \*-------------------------------------------------------------------------*/
 
 void
-plimage(PLFLT **idata, PLINT nx, PLINT ny,
-	PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
-	PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax)
+plimager(PLFLT **idata, PLINT nx, PLINT ny,
+         PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
+         PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax,
+         PLFLT valuemin, PLFLT valuemax)
 {
   PLINT nnx, nny, ix, iy, ixx, iyy, xm, ym;
   PLFLT dx, dy;
+  // Zf holds transformed image pixel values
+  // szmin and szmax are zmin and zmax scaled to unsigned short values
   unsigned short *Zf, szmin, szmax;
   short *Xf, *Yf;
-  PLFLT lzmin, lzmax, tz;
+  // This is used when looping through the image array, checking to
+  // make sure the values are within an acceptable range.
+  PLFLT datum;
 
   if (plsc->level < 3) {
     plabort("plimage: window must be set up first");
@@ -180,8 +197,8 @@ plimage(PLFLT **idata, PLINT nx, PLINT ny,
     return;
   }
 
-  if (Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax){
-    plabort("plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xminor xmax or ymin or ymax.");
+  if (Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax) {
+    plabort("plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xmin or xmax or ymin or ymax.");
     return;
   }
 
@@ -196,38 +213,41 @@ plimage(PLFLT **idata, PLINT nx, PLINT ny,
     }
 
   xm = floor((Dxmin-xmin)/dx); ym = floor((Dymin-ymin)/dy);
-  lzmin = lzmax = idata[xm][ym];
-
-  for (ix=xm; ix<xm+nnx; ix++) {
-    for (iy=ym; iy<ym+nny; iy++) {
-      tz = idata[ix][iy];
-      if (lzmax < tz)
-	lzmax = tz;
-      if (lzmin > tz)
-	lzmin = tz;
-    }
-  }
 
+  // Go through the image values and scale them to fit in an
+  // unsigned short range.
+  // Any values greater than valuemax are set to valuemax,
+  // and values less than valuemin are set to valuemin.
   ixx=-1;
   for (ix=xm; ix<xm+nnx; ix++) {
     ixx++; iyy=0;
-    for (iy=ym; iy<ym+nny; iy++)
-      Zf[ixx*nny+iyy++] = (idata[ix][iy] - lzmin)/(lzmax-lzmin)*USHRT_MAX;
+    for (iy=ym; iy<ym+nny; iy++) {
+      datum = idata[ix][iy];
+      if (datum < valuemin) {
+        datum = valuemin;
+      }
+      else if (datum > valuemax) {
+        datum = valuemax;
+      }
+      Zf[ixx*nny+iyy++] =
+        (datum - valuemin) / (valuemax - valuemin) * USHRT_MAX;
+    }
   }
 
   if (zmin == zmax) {
-    zmin = lzmin;
-    zmax = lzmax;
-  } else {
-    if (zmin < lzmin)
-      zmin = lzmin;
-
-    if (zmax > lzmax)
-      zmax = lzmax;
+    zmin = valuemin;
+    zmax = valuemax;
+  }
+  else {
+    if (zmin < valuemin)
+      zmin = valuemin;
+    if (zmax > valuemax)
+      zmax = valuemax;
   }
 
-  szmin = (zmin - lzmin)/(lzmax-lzmin)*USHRT_MAX;
-  szmax = (zmax - lzmin)/(lzmax-lzmin)*USHRT_MAX;
+  // The value range to plot, scaled to unsigned short values
+  szmin = (zmin - valuemin) / (valuemax - valuemin) * USHRT_MAX;
+  szmax = (zmax - valuemin) / (valuemax - valuemin) * USHRT_MAX;
 
   xmin = Dxmin;  xmax = Dxmax;
   ymin = Dymin;  ymax = Dymax;
@@ -245,11 +265,12 @@ plimage(PLFLT **idata, PLINT nx, PLINT ny,
   dx = dx*(nx-1)/nx;
   dy = dy*(ny-1)/ny;
 
-  for (ix = 0; ix < nnx; ix++)
+  for (ix = 0; ix < nnx; ix++) {
     for (iy = 0; iy < nny; iy++) {
       Xf[ix*nny+iy] =  plP_wcpcx(xmin + ix*dx);
       Yf[ix*nny+iy] =  plP_wcpcy(ymin + iy*dy);
     }
+  }
 
   plP_image(Xf, Yf, Zf, nnx, nny, xmin, ymin, dx, dy, szmin, szmax);
 
@@ -257,3 +278,55 @@ plimage(PLFLT **idata, PLINT nx, PLINT ny,
   free(Yf);
   free(Zf);
 }
+
+/*-------------------------------------------------------------------------*\
+ * plimage
+ *           (***** SUBJECT TO CHANGE ******)
+ *
+ * arguments are
+ *   idata: array containing image data
+ *   nx: dimension of the array in the X axis.
+ *   ny: dimension of the  array in the Y axis
+ *   The array data is indexed like data[ix][iy]
+ *
+ *   xmin, xmax, ymin, ymax:
+ *       data[0][0] corresponds to (xmin,ymin)
+ *       data[nx-1][ny-1] to (xmax,ymax)
+ *
+ *   zmin, zmax:
+ *       only data within bounds zmin <= data <= zmax will be
+ *       plotted. If zmin == zmax, all data will be ploted.
+ *
+ *   Dxmin, Dxmax, Dymin, Dymax:
+ *       plots only the window of points whose(x,y)'s fall
+ *       inside the [Dxmin->Dxmax]X[Dymin->Dymax] window
+ *
+\*-------------------------------------------------------------------------*/
+
+void
+plimage(PLFLT **idata, PLINT nx, PLINT ny,
+	PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
+	PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax)
+{
+  PLINT ix, iy;
+  PLFLT data_min, data_max, iz;
+
+  // Find the minimum and maximum values in the image, and automatically
+  // scale the colors scale over this range.
+  data_min = data_max = idata[0][0];
+
+  for (ix = 0; ix < nx; ix++) {
+    for (iy = 0; iy < ny; iy++) {
+      iz = idata[ix][iy];
+      if (data_max < iz)
+	data_max = iz;
+      if (data_min > iz)
+	data_min = iz;
+    }
+  }
+
+  // Call plimager with the value -> color range mapped to the minimum
+  // and maximum values in idata.
+  plimager(idata, nx, ny, xmin, xmax, ymin, ymax, zmin, zmax,
+           Dxmin, Dxmax, Dymin, Dymax, data_min, data_max);
+}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel

Reply via email to