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