[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: IDLgrAxis expanding

About a half hour ago I wrote this in response to a question
by Pavel Romashkin:  

> > When an instance of IDLgrAxis is created without /EXACT keyword, it is
> > adjusted by IDL so that tick labels are nicely rounded. However, this
> > has a side effect of non-/EXACT axis extending past the limit of the
> > VIEWPLANE_RECTANGLE for the parent IDLgrView. Sometimes this expansion
> > is really large.  Is there a way to make IDLgrAxis to round ticks but
> > lie inside the VIEWPLANE_RECTANGLE? 
> If there is a way, it must be undocumented. :-(

Just after I finished this article (it being rather late) I said
to myself, "The hell with it, I'm going to have a beer". Of course,
I was out of beer. So on the drive to the liquor store the solution
came to me. :-)

I reasoned this way. *Someone* has to know the actual range of
the data, since it clearly gets drawn. Who is it who knows and
how can I get at that information? Using my best Sherlock
impersonation, I finally realized that it is the text object
that creates the labels that knows how long the axis is. So
how do I get at the labels? Humm. The STRINGS keyword! OK.

So here is how it is done. (It's a bit convoluted here,
but it's a solution programmers will love.) I'm showing
here just the calculations for the dependent data axis,
but the other axes will be done in the same way:


   ; Get the range of the data.

thisPlot->GetProperty, XRange=xrange, YRange=yrange

    ; Set up the scaling so that the axes for the plot and the
    ; plot data extends from 0->1 in the X and Y directions.

xs = Normalize(xrange)
ys = Normalize(yrange)

   ; Create the Y axis.

yAxis1 = Obj_New("IDLgrAxis", 1, Color=[255,255,0], Ticklen=0.025, $
    Minor=4, Title=ytitle, Range=yrange, YCoord_conv=ys, $
    Location=[0, 1000, 0])

   ; Get the text object containing the labels.

yAxis1->GetProperty, Ticktext=yAxisText

   ; Get the strings.

yAxisText->GetProperty, Strings=theseStrings

   ; Find the first and last of these strings. This is the REAL
   ; axis range.

nstrings = N_Elements(theseStrings)
minRange = Float(theseStrings[0])
maxRange = Float(theseStrings[nstrings-1])
newRange = [minRange, maxRange]

   ; Set the axis range to the REAL range.

yAxis1->SetProperty, Range=newRange

   ; Find new scaling values for this REAL range.

newYs = Normalize([minrange, maxrange])

   ; Re-scale both the axis AND the data into this new range.

yAxis1->SetProperty, Range=newRange, YCoord_Conv=newYs
thisPlot->SetProperty, YCoord_Conv=newYs


Works real good on my example program, even if it *is* a 
bit of a hack. :-)



David Fanning, Ph.D.
Fanning Software Consulting
Phone: 970-221-0438 E-Mail: davidf@dfanning.com
Coyote's Guide to IDL Programming: http://www.dfanning.com/
Toll-Free IDL Book Orders: 1-888-461-0155