[yt-svn] commit/yt: MatthewTurk: Merged in ngoldbaum/yt (pull request #1600)

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Mon Jun 1 12:28:14 PDT 2015


1 new commit in yt:

https://bitbucket.org/yt_analysis/yt/commits/4da925e20253/
Changeset:   4da925e20253
Branch:      yt
User:        MatthewTurk
Date:        2015-06-01 19:28:03+00:00
Summary:     Merged in ngoldbaum/yt (pull request #1600)

annotate_scale improvements
Affected #:  2 files

diff -r ac0abcc06c420713e8e4dba44178a0c5e3854267 -r 4da925e2025330de13160f8cf4ad20fb44932023 yt/visualization/base_plot_types.py
--- a/yt/visualization/base_plot_types.py
+++ b/yt/visualization/base_plot_types.py
@@ -54,6 +54,7 @@
             self._type_name = "CuttingPlane"
         else:
             self._type_name = viewer._plot_type
+        self.aspect = window_plot._aspect
         self.font_properties = font_properties
         self.font_color = font_color
 

diff -r ac0abcc06c420713e8e4dba44178a0c5e3854267 -r 4da925e2025330de13160f8cf4ad20fb44932023 yt/visualization/plot_modifications.py
--- a/yt/visualization/plot_modifications.py
+++ b/yt/visualization/plot_modifications.py
@@ -23,6 +23,7 @@
 
 from matplotlib.patches import Circle
 from matplotlib.colors import colorConverter
+from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
 
 from yt.funcs import *
 from yt.extern.six import add_metaclass
@@ -1665,11 +1666,11 @@
         # Setting pos overrides corner argument
         if self.pos[0] is None or self.pos[1] is None:
             if self.corner == 'upper_left':
-                self.pos = (0.03, 0.97)
+                self.pos = (0.03, 0.96)
                 self.text_args['horizontalalignment'] = 'left'
                 self.text_args['verticalalignment'] = 'top'
             elif self.corner == 'upper_right':
-                self.pos = (0.97, 0.97)
+                self.pos = (0.97, 0.96)
                 self.text_args['horizontalalignment'] = 'right'
                 self.text_args['verticalalignment'] = 'top'
             elif self.corner == 'lower_left':
@@ -1726,47 +1727,49 @@
 class ScaleCallback(PlotCallback):
     """
     annotate_scale(corner='lower_right', coeff=None, unit=None, pos=None,
-                   max_frac=0.2, min_frac=0.018, coord_system='axis',
-                   text_args=None, plot_args=None)
+                   max_frac=0.16, min_frac=0.015, coord_system='axis',
+                   size_bar_args=None, draw_inset_box=False, 
+                   inset_box_args=None)
 
     Annotates the scale of the plot at a specified location in the image
     (either in a preset corner, or by specifying (x,y) image coordinates with
-    the pos argument.  Coeff and units (e.g. 1 Mpc or 100 kpc) refer to the 
-    distance scale you desire to show on the plot.  If no coeff and units are 
-    specified, an appropriate pair will be determined such that your scale bar 
-    is never smaller than min_frac or greater than max_frac of your plottable 
-    axis length.  For additional text and plot arguments for the text and line,
-    include them as dictionaries to pass to text_args and plot_args.
-    
+    the pos argument.  Coeff and units (e.g. 1 Mpc or 100 kpc) refer to the
+    distance scale you desire to show on the plot.  If no coeff and units are
+    specified, an appropriate pair will be determined such that your scale bar
+    is never smaller than min_frac or greater than max_frac of your plottable
+    axis length.  Additional customization of the scale bar is possible by
+    adjusting the size_bar_args dictionary.  This accepts keyword arguments
+    for the AnchoredSizeBar class in matplotlib's axes_grid toolkit.
+
     Parameters
     ----------
 
     corner : string, optional
-        Corner sets up one of 4 predeterimined locations for the timestamp
+        Corner sets up one of 4 predeterimined locations for the scale bar
         to be displayed in the image: 'upper_left', 'upper_right', 'lower_left',
-        'lower_right' (also allows None). This value will be overridden by the 
+        'lower_right' (also allows None). This value will be overridden by the
         optional 'pos' keyword.
 
     coeff : float, optional
         The coefficient of the unit defining the distance scale (e.g. 10 kpc or
-        100 Mpc) for overplotting.  If set to None along with unit keyword, 
+        100 Mpc) for overplotting.  If set to None along with unit keyword,
         coeff will be automatically determined to be a power of 10
         relative to the best-fit unit.
 
     unit : string, optional
-        unit must be a valid yt distance unit (e.g. 'm', 'km', 'AU', 'pc', 
+        unit must be a valid yt distance unit (e.g. 'm', 'km', 'AU', 'pc',
         'kpc', etc.) or set to None.  If set to None, will be automatically
         determined to be the best-fit to the data.
 
     pos : 2- or 3-element tuples, lists, or arrays, optional
-        The image location of the timestamp in the coord system defined by the
-        coord_system kwarg.  Setting pos overrides the corner parameter.
+        The image location of the scale bar in the plot coordinate system.
+        Setting pos overrides the corner parameter.
 
     min_frac, max_frac: float, optional
-        The minimum/maximum fraction of the axis width for the scale bar to 
+        The minimum/maximum fraction of the axis width for the scale bar to
         extend. A value of 1 would allow the scale bar to extend across the
-        entire axis width.  Only used for automatically calculating 
-        best-fit coeff and unit when neither is specified, otherwise 
+        entire axis width.  Only used for automatically calculating
+        best-fit coeff and unit when neither is specified, otherwise
         disregarded.
 
     coord_system : string, optional
@@ -1783,17 +1786,23 @@
             "figure" -- the MPL figure coordinates: (0,0) is lower left, (1,1)
                         is upper right
 
-    text_args : dictionary, optional
-        A dictionary of any arbitrary parameters to be passed to the Matplotlib
-        text object.  Defaults: {'color':'white', 
-        'horizontalalignment':'center', 'verticalalignment':'top'}.
+    size_bar_args : dictionary, optional
+        A dictionary of parameters to be passed to the Matplotlib
+        AnchoredSizeBar initializer.
+        Defaults: {'pad': 0.25, 'sep': 5, 'borderpad': 1, 'color': 'w'}
 
-    plot_args : dictionary, optional
-        A dictionary of any arbitrary parameters to be passed to the Matplotlib
-        line object.  Defaults: {'color':'white', 'linewidth':3}.
+    draw_inset_box : boolean, optional
+        Whether or not an inset box should be included around the scale bar.
+
+    inset_box_args : dictionary, optional
+        A dictionary of keyword arguments to be passed to the matplotlib Patch
+        object that represents the inset box.
+        Defaults: {'facecolor': 'black', 'linewidth': 3, 'edgecolor', 'white',
+                   'alpha': 0.5, 'boxstyle': 'square'}
+
 
     Example
-    ------- 
+    -------
 
     >>> import yt
     >>> ds = yt.load('Enzo_64/DD0020/data0020')
@@ -1802,11 +1811,23 @@
     """
     _type_name = "scale"
     def __init__(self, corner='lower_right', coeff=None, unit=None, pos=None, 
-                 max_frac=0.20, min_frac=0.018, coord_system='axis',
-                 text_args=None, plot_args=None):
+                 max_frac=0.16, min_frac=0.015, coord_system='axis',
+                 size_bar_args=None, draw_inset_box=False, inset_box_args=None):
 
-        def_text_args = {'color':'white'}
-        def_plot_args = {'color':'white', 'linewidth':3}
+        def_size_bar_args = {
+            'pad': 0.05,
+            'sep': 5,
+            'borderpad': 1,
+            'color': 'w'
+        }
+
+        inset_box_args = {
+            'facecolor': 'black',
+            'linewidth': 3,
+            'edgecolor': 'white',
+            'alpha': 0.5,
+            'boxstyle': 'square',
+        }
 
         # Set position based on corner argument.
         self.corner = corner
@@ -1816,33 +1837,34 @@
         self.max_frac = max_frac
         self.min_frac = min_frac
         self.coord_system = coord_system
-        if text_args is None: text_args = def_text_args
-        self.text_args = text_args
-        # This assures the line and the text are aligned
-        self.text_args['horizontalalignment'] = 'center'
-        self.text_args['verticalalignment'] = 'top'
-        if plot_args is None: plot_args = def_plot_args
-        self.plot_args = plot_args
+        if size_bar_args is None:
+            self.size_bar_args = def_size_bar_args
+        else:
+            self.size_bar_args = size_bar_args
+        if inset_box_args is None:
+            self.inset_box_args = def_inset_box_args
+        else:
+            self.inset_box_args = inset_box_args
+        self.draw_inset_box = draw_inset_box
 
     def __call__(self, plot):
         # Callback only works for plots with axis ratios of 1
         xsize = plot.xlim[1] - plot.xlim[0]
-        ysize = plot.ylim[1] - plot.ylim[0]
-        if xsize != ysize:
-            raise RuntimeError("Scale callback only works for plots with "
-                               "axis ratios of 1. Here: xsize = %s, ysize "
-                               " = %s." % (xsize, ysize))
+        if plot.aspect != 1.0:
+            raise NotImplementedError(
+                "Scale callback has only been implemented for plots with no "
+                "aspect ratio scaling. (aspect = {%s})".format(plot._aspect))
 
         # Setting pos overrides corner argument
         if self.pos is None:
             if self.corner == 'upper_left':
-                self.pos = (0.12, 0.971)
+                self.pos = (0.11, 0.952)
             elif self.corner == 'upper_right':
-                self.pos = (0.88, 0.971)
+                self.pos = (0.89, 0.952)
             elif self.corner == 'lower_left':
-                self.pos = (0.12, 0.062)
+                self.pos = (0.11, 0.052)
             elif self.corner == 'lower_right':
-                self.pos = (0.88, 0.062)
+                self.pos = (0.89, 0.052)
             elif self.corner is None:
                 self.pos = (0.5, 0.5)
             else:
@@ -1851,8 +1873,8 @@
                                   "'lower_right', or None")
 
         # When identifying a best fit distance unit, do not allow scale marker
-        # to be greater than max_frac fraction of xaxis or under min_frac 
-        # fraction of xaxis 
+        # to be greater than max_frac fraction of xaxis or under min_frac
+        # fraction of xaxis
         max_scale = self.max_frac * xsize
         min_scale = self.min_frac * xsize
 
@@ -1861,30 +1883,38 @@
 
         # If no units are set, then identify a best fit distance unit
         if self.unit is None:
-            min_scale = plot.ds.get_smallest_appropriate_unit(min_scale, 
-                                                   return_quantity=True)
-            max_scale = plot.ds.get_smallest_appropriate_unit(max_scale, 
-                                                   return_quantity=True)
+            min_scale = plot.ds.get_smallest_appropriate_unit(
+                min_scale, return_quantity=True)
+            max_scale = plot.ds.get_smallest_appropriate_unit(
+                max_scale, return_quantity=True)
             self.coeff = max_scale.v
             self.unit = max_scale.units
         self.scale = YTQuantity(self.coeff, self.unit)
-        self.text = "{scale} {units}".format(scale=int(self.coeff), 
-                                             units=self.unit)
-        image_scale = (plot.frb.convert_distance_x(self.scale) / \
+        text = "{scale} {units}".format(scale=int(self.coeff), units=self.unit)
+        image_scale = (plot.frb.convert_distance_x(self.scale) /
                        plot.frb.convert_distance_x(xsize)).v
 
-        # This is just a fancy wrapper around the TextLabelCallback and the
-        # ImageLineCallback
-        pos_line_start = (self.pos[0]-image_scale/2, self.pos[1]+0.01)
-        pos_line_end = (self.pos[0]+image_scale/2, self.pos[1]+0.01)
-        icb = LinePlotCallback(pos_line_start, pos_line_end, 
-                               coord_system=self.coord_system, 
-                               plot_args=self.plot_args)
-        icb(plot)
-        tcb = TextLabelCallback(self.pos, self.text, 
-                                coord_system=self.coord_system,
-                                text_args=self.text_args)
-        return tcb(plot)
+        size_vertical = self.size_bar_args.pop('size_vertical', .005)
+        fontproperties = self.size_bar_args.pop(
+            'fontproperties', plot.font_properties)
+        frameon = self.size_bar_args.pop('frameon', self.draw_inset_box)
+
+        # this "anchors" the size bar to a box centered on self.pos in axis
+        # coordinates
+        self.size_bar_args['bbox_to_anchor'] = self.pos
+        self.size_bar_args['bbox_transform'] = plot._axes.transAxes
+
+        bar = AnchoredSizeBar(plot._axes.transAxes, image_scale, text, 10,
+                              size_vertical=size_vertical,
+                              fontproperties=fontproperties,
+                              frameon=frameon,
+                              **self.size_bar_args)
+
+        bar.patch.set(**self.inset_box_args)
+
+        plot._axes.add_artist(bar)
+
+        return plot
 
 class RayCallback(PlotCallback):
     """

Repository URL: https://bitbucket.org/yt_analysis/yt/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


More information about the yt-svn mailing list