Hi,

I'll continue my current flood of emails to the list. :) I'm finally getting back to my work on Skew-T plots, and I have a semi-working implementation (attached.) It runs, and as is, plots up some of the grid, with the x-value grid lines skewed 45 degrees to the right (as they should be.) The problem is as you resize the plot horizontally, some weird things happen. First, some of the lines that start overlaid end up separating as you expand the plot. The difference is between what is added using ax.plot and what is added using ax.vlines. The former adds Line2D objects while the latter adds a LineCollection which is holding path objects. I'm really not sure what's going on there. I'm not done checking it out yet, but I'm curious if anyone has any ideas off the top of their head.

The second issue, which is more pressing, is when you resize vertically, the axes limits of the plot don't change (good), but unfortunately the lines don't stay connected to their lower y-coordinate in data space (bad). I'm really needing to draw things in a coordinate system that's independant of the data scale but also doesn't depend on the aspect ratio of the axes, so that I can get lines (and data plots) where the x gridlines are always at a 45 degree angle and the lower Y-value point stays fixed. By problem right now is that while I can find the lower left corner in pixel space and use that to do the proper adjustments, this changes when you resize. This changing is especially important in the y-direction. What I need is either of:

        1) Axes space adjusted for aspect ratio (and updated with resizes)
        2) Pixel space relative to some corner of the axes

Or something similar that I don't know about. Any thoughts, or do I just need to come up with some magical combination of transforms that works? You can see what I have so far in my attached file.

Thanks in advance,

Ryan

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma
from matplotlib.axes import Axes
from matplotlib.path import Path
from matplotlib.lines import Line2D
from matplotlib.ticker import Formatter, Locator, NullLocator, FixedLocator, NullFormatter, AutoLocator, ScalarFormatter
from matplotlib import transforms
from matplotlib.projections import register_projection

import numpy as np

# This example projection class is rather long, but it is designed to
# illustrate many features, not all of which will be used every time.
# It is also common to factor out a lot of these methods into common
# code used by a number of projections with similar characteristics
# (see geo.py).

class SkewXAxes(Axes):
    # The projection must specify a name.  This will be used be the
    # user to select the projection, i.e. ``subplot(111,
    # projection='skewx')``.
    name = 'skewx'

##    def __init__(self, *args, **kwargs):
##        Axes.__init__(self, *args, **kwargs)
#        self.set_aspect(1.0, adjustable='box', anchor='C')
#        self.cla()

    def _set_lim_and_transforms(self):
        """
        This is called once when the plot is created to set up all the
        transforms for the data, text and grids.
        """
        # There are three important coordinate spaces going on here:
        #
        #    1. Data space: The space of the data itself
        #
        #    2. Axes space: The unit rectangle (0, 0) to (1, 1)
        #       covering the entire plot area.
        #
        #    3. Display space: The coordinates of the resulting image,
        #       often in pixels or dpi/inch.
        self.transAxes = transforms.BboxTransformTo(self.bbox)

        self.transScale = transforms.TransformWrapper(
            transforms.IdentityTransform())

        self.transLimits = transforms.BboxTransformFrom(
            transforms.TransformedBbox(self.viewLim, self.transScale))

        # This shifts to the lower left corner in pixel space
        shift = transforms.ScaledTranslation(0, 0,
            self.transAxes + transforms.Affine2D().scale(-1,-1))

        # Shift to the lower left corner, do the skew, and shift back
        self.transProjection = shift + self.SkewXTransform() + shift.inverted()

        # Normal transform for things
        _non_skewed = self.transScale + (self.transLimits + self.transAxes)

        # Full data transform
        self.transData = _non_skewed + self.transProjection
            
        self._xaxis_transform = transforms.blended_transform_factory(
                _non_skewed, self.axes.transAxes)
        self._yaxis_transform = transforms.blended_transform_factory(
                self.axes.transAxes, _non_skewed)

    # Now, the transforms themselves.
    class SkewXTransform(transforms.Transform):
        """
        The base skew transform.
        """
        input_dims = 2
        output_dims = 2
        is_separable = False

        def __init__(self):
            """
            Create a new skew transform. x,y -> x+y,y
            """
            transforms.Transform.__init__(self)
            self._mtx = np.array([[1, 1],[0, 1]])

        def transform(self, xy):
            """
            Override the transform method to implement the custom transform.

            The input and output are Nx2 numpy arrays.
            """
            return np.dot(xy, self._mtx.T)
        transform_affine = transform

        def inverted(self):
            return SkewXAxes.InvertedSkewXTransform()
        inverted.__doc__ = transforms.Transform.inverted.__doc__

    class InvertedSkewXTransform(transforms.Transform):
        input_dims = 2
        output_dims = 2
        is_separable = False

        def __init__(self):
            transforms.Transform.__init__(self)
            self._mtx = np.array([[1, -1],[0, 1]])

        def transform(self, xy):
            return np.dot(xy, self._mtx.T)
        transform.__doc__ = transforms.Transform.transform.__doc__
        transform_affine = transform

        def inverted(self):
            # The inverse of the inverse is the original transform... ;)
            return SkewXAxes.SkewXTransform()
        inverted.__doc__ = transforms.Transform.inverted.__doc__

# Now register the projection with matplotlib so the user can select
# it.
register_projection(SkewXAxes)

# Now make a simple example using the custom projection.
import matplotlib.pyplot as plt

fig = plt.figure(1, figsize=(6.5875, 6.2125))
fig.clf()
ax = fig.add_subplot(111)

plt.grid(True)
#p,h,T,Td = np.loadtxt('sounding.txt', usecols=range(0,4), unpack=True)
#ax.semilogy(T, p, 'r')

ax.vlines(np.arange(-40,45,10), 1050, 100)
l = ax.vlines(-30,1050,100,'g')
v = l._paths[0].vertices
l2, = ax.plot(np.array([-10]*7), np.arange(1000, 300, -100), 'r')
l3 = Line2D(v[:,0], v[:,1])
ax.add_line(l3)
ax.autoscale_view(False)
ax.set_xlim(-40,45)
ax.set_ylim(1050,100)
plt.draw()
plt.show()
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to