[Yt-svn] yt-commit r787 - trunk/yt/raven

mturk at wrangler.dreamhost.com mturk at wrangler.dreamhost.com
Thu Sep 18 01:47:14 PDT 2008


Author: mturk
Date: Thu Sep 18 01:47:13 2008
New Revision: 787
URL: http://yt.spacepope.org/changeset/787

Log:
Added a ParticlePlot.  Doesn't do colorbars yet, but will color by fields.

ParticleCallback's interface is slightly more advanced now, too, accepting
fields and strides.  (Still reads the whole field off disk, but doesn't plot
it.)



Modified:
   trunk/yt/raven/Callbacks.py
   trunk/yt/raven/ColorMaps.py
   trunk/yt/raven/PlotCollection.py
   trunk/yt/raven/PlotTypes.py
   trunk/yt/raven/__init__.py

Modified: trunk/yt/raven/Callbacks.py
==============================================================================
--- trunk/yt/raven/Callbacks.py	(original)
+++ trunk/yt/raven/Callbacks.py	Thu Sep 18 01:47:13 2008
@@ -82,7 +82,7 @@
         plot._axes.hold(False)
 
 class ParticleCallback(PlotCallback):
-    def __init__(self, axis, width, p_size=1.0, col='k'):
+    def __init__(self, axis, width, p_size=1.0, col='k', stride=1.0):
         """
         Adds particle positions, based on a thick slab along *axis* with a
         *width* along the line of sight.  *p_size* controls the number of
@@ -93,31 +93,53 @@
         self.width = width
         self.p_size = p_size
         self.color = col
+        if check_color(col):
+            self.color_field = False
+        else:
+            self.color_field = True
         self.field_x = "particle_position_%s" % lagos.axis_names[lagos.x_dict[axis]]
         self.field_y = "particle_position_%s" % lagos.axis_names[lagos.y_dict[axis]]
         self.field_z = "particle_position_%s" % lagos.axis_names[axis]
+        self.stride = stride
+        self.particles_x = self.particles_y = self.particles_z = None
+
+    def _setup_particles(self, data):
+        if self.particles_x is not None: return
+        grids = data._grids
+        particles_x = []; particles_y = []; particles_z = [];
+        for g in grids:
+            particles_x.append(g[self.field_x][::self.stride])
+            particles_y.append(g[self.field_y][::self.stride])
+            particles_z.append(g[self.field_z][::self.stride])
+        self.particles_x = na.concatenate(particles_x); del particles_x
+        self.particles_y = na.concatenate(particles_y); del particles_y
+        self.particles_z = na.concatenate(particles_z); del particles_z
+        if not self.color_field: return
+        particles_c = []
+        for g in grids:
+            particles_c.append(g[self.color][::self.stride])
+        self.particles_c = na.log10(na.concatenate(particles_c)); del particles_c
 
     def __call__(self, plot):
         z0 = plot.data.center[self.axis] - self.width/2.0
         z1 = plot.data.center[self.axis] + self.width/2.0
-        grids = plot.data._grids
-        particles_x = na.concatenate([g[self.field_x] for g in grids]).ravel()
-        particles_y = na.concatenate([g[self.field_y] for g in grids]).ravel()
-        particles_z = na.concatenate([g[self.field_z] for g in grids]).ravel()
-        if len(particles_x) == 0: return
+        self._setup_particles(plot.data)
+        if len(self.particles_x) == 0: return
         x0, x1 = plot.xlim
         y0, y1 = plot.ylim
         xx0, xx1 = plot._axes.get_xlim()
         yy0, yy1 = plot._axes.get_ylim()
         # Now we rescale because our axes limits != data limits
-        goodI = na.where( (particles_x < x1) & (particles_x > x0)
-                        & (particles_y < y1) & (particles_y > y0)
-                        & (particles_z < z1) & (particles_z > z0))
-        particles_x = (particles_x[goodI] - x0) * (xx1-xx0)/(x1-x0)
-        particles_y = (particles_y[goodI] - y0) * (yy1-yy0)/(y1-y0)
+        goodI = na.where( (self.particles_x < x1) & (self.particles_x > x0)
+                        & (self.particles_y < y1) & (self.particles_y > y0)
+                        & (self.particles_z < z1) & (self.particles_z > z0))
+        particles_x = (self.particles_x[goodI] - x0) * (xx1-xx0)/(x1-x0)
+        particles_y = (self.particles_y[goodI] - y0) * (yy1-yy0)/(y1-y0)
+        if not self.color_field: particles_c = self.color
+        else: particles_c = self.particles_c[goodI]
         plot._axes.hold(True)
         plot._axes.scatter(particles_x, particles_y, edgecolors='None',
-                          s=self.p_size, c=self.color)
+                           s=self.p_size, c=particles_c)
         plot._axes.set_xlim(xx0,xx1)
         plot._axes.set_ylim(yy0,yy1)
         plot._axes.hold(False)
@@ -370,6 +392,46 @@
                                      **self.plot_args)
         plot._axes.hold(False)
 
+class PointAnnotateCallback(PlotCallback):
+    def __init__(self, pos, text, text_args = None):
+        self.pos = pos
+        self.text = text
+        self.text_args = text_args
+
+    def __call__(self, plot):
+        x,y = self.convert_to_pixels(plot, self.pos)
+        plot._axes.text(x, y, self.text, **self.text_args)
+
+class SphereCallback(PlotCallback):
+    def __init__(self, center, radius, circle_args = None,
+                 text = None, text_args = None):
+        self.center = center
+        self.radius = radius
+        self.circle_args = circle_args
+        self.text = text
+        self.text_args = text_args
+
+    def __call__(self, plot):
+        from matplotlib.patches import Circle
+        x0, x1 = plot.xlim
+        y0, y1 = plot.ylim
+        l, b, width, height = plot._axes.bbox.get_bounds()
+        xi = lagos.x_dict[plot.data.axis]
+        yi = lagos.y_dict[plot.data.axis]
+        dx = plot.image._A.shape[0] / (x1-x0)
+        dy = plot.image._A.shape[1] / (y1-y0)
+        radius = self.radius * dx
+        center_x = (self.center[xi] - x0)*dx
+        center_y = (self.center[yi] - y0)*dy
+        cir = Circle((center_x, center_y), radius, fill=False,
+                     **self.circle_args)
+        plot._axes.add_patch(cir)
+        if self.text is not None:
+            plot._axes.text(center_x, center_y, "%s" % halo.id,
+                            **self.text_args)
+
+        
+
 class HopCircleCallback(PlotCallback):
     def __init__(self, hop_output, axis, max_number=None,
                  annotate=False):

Modified: trunk/yt/raven/ColorMaps.py
==============================================================================
--- trunk/yt/raven/ColorMaps.py	(original)
+++ trunk/yt/raven/ColorMaps.py	Thu Sep 18 01:47:13 2008
@@ -26,6 +26,13 @@
 import matplotlib.colors as cc
 import matplotlib.cm as mcm
 
+def check_color(name):
+    try:
+        ss = cc.colorConverter.to_rgb(name)
+        return True
+    except ValueError:
+        return False
+
 raven_colormaps = {}
 
 def add_cmap(name, cdict):

Modified: trunk/yt/raven/PlotCollection.py
==============================================================================
--- trunk/yt/raven/PlotCollection.py	(original)
+++ trunk/yt/raven/PlotCollection.py	Thu Sep 18 01:47:13 2008
@@ -180,6 +180,14 @@
         p["Axis"] = lagos.axis_names[axis]
         return p
 
+    def add_particles(self, axis, width, p_size=1.0, col='k', stride=1.0,
+                      data_source=None):
+        if data_source is None: data_source = self.pf.h.sphere([0.5]*3,1)
+        p = self._add_plot(PlotTypes.ParticlePlot(data_source, axis,
+                                        width, p_size, col, stride))
+        p["Axis"] = lagos.axis_names[axis]
+        return p
+
     def add_cutting_plane(self, field, normal,
                           center=None, use_colorbar=True,
                           figure = None, axes = None, fig_size=None, obj=None):

Modified: trunk/yt/raven/PlotTypes.py
==============================================================================
--- trunk/yt/raven/PlotTypes.py	(original)
+++ trunk/yt/raven/PlotTypes.py	Thu Sep 18 01:47:13 2008
@@ -213,24 +213,13 @@
         self.datalabel = label
         if self.colorbar != None: self.colorbar.set_label(str(label))
 
-class VMPlot(RavenPlot):
-    _antialias = True
-    _period = (0.0, 0.0)
-    def __init__(self, data, field, figure = None, axes = None,
-                 use_colorbar = True, size=None, periodic = False):
-        fields = ['X', 'Y', field, 'X width', 'Y width']
-        if not size:
-            size = (10,8)
-            if not use_colorbar: size=(8,8)
-        RavenPlot.__init__(self, data, fields, figure, axes, size=size)
-        self._figure.subplots_adjust(hspace=0, wspace=0, bottom=0.0,
-                                    top=1.0, left=0.0, right=1.0)
+    def setup_domain_edges(self, axis, periodic=False):
         DLE = self.data.pf["DomainLeftEdge"]
         DRE = self.data.pf["DomainRightEdge"]
         DD = float(periodic)*(DRE - DLE)
-        if self.data.axis < 3:
-            xax = lagos.x_dict[self.data.axis]
-            yax = lagos.y_dict[self.data.axis]
+        if axis < 3:
+            xax = lagos.x_dict[axis]
+            yax = lagos.y_dict[axis]
             self.xmin = DLE[xax] - DD[xax]
             self.xmax = DRE[xax] + DD[xax]
             self.ymin = DLE[yax] - DD[yax]
@@ -241,6 +230,20 @@
             # in the Orion case.  Cutting planes are tricky.
             self.xmin = self.ymin = 0.0
             self.xmax = self.ymax = 1.0
+
+class VMPlot(RavenPlot):
+    _antialias = True
+    _period = (0.0, 0.0)
+    def __init__(self, data, field, figure = None, axes = None,
+                 use_colorbar = True, size=None, periodic = False):
+        fields = ['X', 'Y', field, 'X width', 'Y width']
+        if not size:
+            size = (10,8)
+            if not use_colorbar: size=(8,8)
+        RavenPlot.__init__(self, data, fields, figure, axes, size=size)
+        self._figure.subplots_adjust(hspace=0, wspace=0, bottom=0.0,
+                                    top=1.0, left=0.0, right=1.0)
+        self.setup_domain_edges(self.data.axis, periodic)
         self.cmap = None
         self.__setup_from_field(field)
         self.__init_temp_image(use_colorbar)
@@ -413,7 +416,8 @@
         if self.colorbar != None: self.colorbar.set_label(str(data_label))
 
 class SlicePlotNaturalNeighbor(SlicePlot):
-    
+    _type_name = "NNSlice"
+
     def _get_buff(self, width=None):
         import delaunay as de
         x0, x1 = self.xlim
@@ -500,6 +504,70 @@
         self.set_ylim(l_edge_y, r_edge_y) # At some point, perhaps calculate them?
         self._redraw_image()
 
+class ParticlePlot(RavenPlot):
+
+    _type_name = "ParticlePlot"
+    def __init__(self, data, axis, width, p_size=1.0, col='k', stride=1.0,
+                 figure = None, axes = None):
+        RavenPlot.__init__(self, data, [], figure, axes)
+        self._figure.subplots_adjust(hspace=0, wspace=0, bottom=0.0,
+                                    top=1.0, left=0.0, right=1.0)
+        self.axis = axis
+        self.setup_domain_edges(axis)
+        self.axis_names['Z'] = col
+        from Callbacks import ParticleCallback
+        self.add_callback(ParticleCallback(axis, width, p_size, col, stride))
+
+    def _redraw_image(self, *args):
+        self._axes.clear() # To help out the colorbar
+        self._reset_image_parameters()
+        self._run_callbacks()
+
+    def set_xlim(self, xmin, xmax):
+        self.xlim = (xmin,xmax)
+
+    def set_ylim(self, ymin, ymax):
+        self.ylim = (ymin,ymax)
+
+    def _generate_prefix(self, prefix):
+        self.prefix = "_".join([prefix, self._type_name, \
+            lagos.axis_names[self.axis], self.axis_names['Z']])
+        self["Field1"] = self.axis_names["Z"]
+        self["Field2"] = None
+        self["Field3"] = None
+
+    def set_width(self, width, unit):
+        self["Unit"] = str(unit)
+        self["Width"] = float(width)
+        if isinstance(unit, types.StringType):
+            unit = self.data.hierarchy[unit]
+        self.width = width / unit
+        self._refresh_display_width()
+
+    def _refresh_display_width(self, width=None):
+        if width:
+            self.width = width
+        else:
+            width = self.width
+        if iterable(width):
+            width_x, width_y = width
+        else:
+            width_x = width
+            width_y = width
+        l_edge_x = self.data.center[lagos.x_dict[self.axis]] - width_x/2.0
+        r_edge_x = self.data.center[lagos.x_dict[self.axis]] + width_x/2.0
+        l_edge_y = self.data.center[lagos.y_dict[self.axis]] - width_y/2.0
+        r_edge_y = self.data.center[lagos.y_dict[self.axis]] + width_y/2.0
+        self.set_xlim(max(l_edge_x,self.xmin), min(r_edge_x,self.xmax))
+        self.set_ylim(max(l_edge_y,self.ymin), min(r_edge_y,self.ymax))
+        self._redraw_image()
+
+    def _reset_image_parameters(self):
+        self._axes.set_xticks(())
+        self._axes.set_yticks(())
+        self._axes.set_ylabel("")
+        self._axes.set_xlabel("")
+
 class ProfilePlot(RavenPlot):
     def setup_bins(self, field, func=None):
         if field in lagos.fieldInfo and lagos.fieldInfo[field].take_log:

Modified: trunk/yt/raven/__init__.py
==============================================================================
--- trunk/yt/raven/__init__.py	(original)
+++ trunk/yt/raven/__init__.py	Thu Sep 18 01:47:13 2008
@@ -55,7 +55,7 @@
 
 vm_axis_names = {0:'x', 1:'y', 2:'z', 3:'dx', 4:'dy'}
 
-from ColorMaps import raven_colormaps, add_cmap
+from ColorMaps import raven_colormaps, add_cmap, check_color
 
 import PlotTypes
 be = PlotTypes



More information about the yt-svn mailing list