| Author |
Topic  |
|
|
Ian Lindsay
UK
8 Posts |
Posted - 04/23/2001 : 10:35:56 AM
|
I am using Origin 5 to plot a graph where, in addition to the standard y-axis tick labels, the reciprocal of each tick label is shown, i.e. 1/(tick label value).
Adding another layer with a linked reciprocal axis is not a particularly satisfactory solution as all the values are bunched up at one end and it isn't possible to get reciprocal values that occur adjacent to the displayed standard tick labels.
A better solution seems to be to plot a scatter graph with data labels then use the "attach to axis" option to position the data labels at the axis of interest. The procedure I am following to do this is to create a data set where the x values are the same and the y values correspond to the standard tick labels. I am then creating a column of the reciprocal y-axis values using "set column values" and set this column as labels, plotting the labelled data as a scatter graph with no symbol (so the data points are hidden) and positioning the labels at the axis.
There are, however, a number of problems with this approach:
1. The data set providing the labels must be edited if the y-axis tick mark spacing is changed, otherwise the reciprocal values do not correspond to displayed tick markers. Is there any way of accessing the tick mark data directly so that the reciprocals can be calculated from that?
2. Using the reciprocal data as described above, it is impossible to re-calculate the label values while the column type is set as "label". To use "set column values" the column must be returned to something which can be a numeric type (eg. x,y,z,none or anything but "labels").
3. If re-calculating in this way while the labels derived from this column are still on the graph, the results appear to be a jumble of random characters. To get the correct results, the plots of the label data set and the data they are labeling must be removed from the graph.
4. Any decimal place control used to format the numerical results when the label values are calculated is lost when the column is returned to labels from a numeric type. There also appears to be no way of controlling decimal places once the column is converted to labels. The only way I have found of getting around this is to set the internal data type to "integer" while the column is in a numeric format, but this only works if you want no decimal places at all.
Any suggestions of solutions to any/all of these problems would be much appreciated.
Ian.
Edited by - Ian Lindsay on 04/23/2001 13:27:42 |
|
|
greg
USA
1380 Posts |
Posted - 04/23/2001 : 2:50:55 PM
|
You are correct that changing the Y scale might require a change in the text for labels, but this can be more-or-less automatic and your approach was almost the 'correct' way to go ...
The instructions below are for your 5.0, so 6.X users may need to modify them slightly.
Step 1 - A new layer There are often situations in Origin where a new layer provides a solution to a perplexing problem. For example, anytime you need to display the same dataset twice (or more times) you need a new layer to overcome the 'data can be displayed once per layer' Origin standard. In this case (and in most cases) we want the new layer linked to the first. In this particular case we want both the X and Y scales to link in a 1 to 1 fashion so the range of the second layer always follows the first.
- With a graph active, select Edit : New Layer(Axes) : (Linked):Top X + Right Y
- Select Format : Layer
- Click the Link Axes... button
- Check Straight (1 to 1) for both the X Axis Link and Y axis Link
- Click OK
- Click OK
You can turn off the top X axis if you wish, but one thing you must do is turn off the right Y axis labels. Double-clicking directly on the labels should bring you to the Y axis - Layer 2, Tick Labels Tab. Uncheck the Show Major Labels and click OK.
Step 2 - Our 'trick' dataset Now we want to create a dataset with Y values that will correspond to Tick locations AND create a text version of those values that will display as Tick Labels - in your case you want inverted values.
- Add three columns to your worksheet
- Make the first of the three an X column (right click in a blank area on the right side of the worksheet an make sure Multiple X Columns is checked)
- Make the last of the three a Label column
- In the middle column enter the Y values for your tick marks displayed on your left Y axis
- For each of these values, enter 0 in the new X column to its left
- Enter values in the Label column (don't worry if their 'right' or not
- Go to your graph window, double click on the Layer 2 icon and 'add' the Y dataset and label dataset to this layer and click OK
Things will look a bit jumbled at the moment, so let's change two things (consult documentation on editing plotted data):
- Edit the Y data so that it's a Scatter plot with zero symbol size
- Edit the label data so that it is attached to the Right Y axis, is rotated zero degrees and give it a 50% X Offset.
Things should look a little better now, but with a little scripting, you should be able to go the last mile. Here is a script that asks you for the first and last tick for layer 1, then calculates the inverted values for layer 2.
page.active=1; getn (First Tick) beg (Last Tick) end (Layer 1 Tick Marks); inc=layer1.y.inc; %M=%(1,@W); %N=%H; win -a %M; for(row=1,ii=beg;ii wcol(3)[row]=0; wcol(4)[row]=ii; nn=1/ii; if(nn==0/0) { %A=\g(); } else { %A=$(nn,*5); // choose this for fixed // %A=$(nn); // choose this for 'auto' } wcol(5)[row]$=%A; }; win -a %N;
The script handles the case where a missing value occurs (Y = 0; 1/Y = missing value) and displays an infinity symbol. As shown it displays 5 decimal places, but there is a line which can be uncommented to display default digits instead.
|
 |
|
|
Ian Lindsay
UK
8 Posts |
Posted - 04/25/2001 : 12:17:24 PM
|
Thanks for that Greg.
Your script gave me a few ideas - specifically using the $ operator to generate the labels with the required number of decimal places, which I probably should have thought of in the first place.
I've now written a script to produce the reciprocal tick-mark labels completely automatically. This is given below. I attached the script to a hidden button on the graph and set the script to run after an axis rescale in the label control dialog. This generates values in a worksheet called "reciprocals" which must then be plotted on the graph as a scatter plus labels with the symbol set to none and the labels attached to the axis with an appropriate offset.
Once plotted, any updates resulting from an axis rescale are automatic. The reciprocal data is plotted in the same layer as the axis of interest.
// Calculate reciprocals of axis tick marks and generate labels // // Requires worksheet named "reciprocals" with 4 columns // set as A(X), B(Y), C(Y), D(L) // Plot C and D as scatter plot with labels // set symbol shape as "no symbol" for plot of C // attach labels from D to appropriate axis and set offset as necessary // // Layer and axis settings should be modified below as required //
ymin=layer2.Y2.from; // gets axis start value ymax=layer2.Y2.to; // gets axis end value yinc=layer2.Y2.inc; // gets axis major tick increment
// determine first non-zero tick marker value from start of axis // and start calculating reciprocals from here
stint=nint(ymin/yinc); if((stint*yinc) < ymin) start=(stint+1)*yinc; else start=stint*yinc; if(start==0) start=yinc;
// now generate a set of data points at y-axis values corresponding to the major tick marks // and a set of labels containing the reciprocals of these values
for(i=start,j=1;i<=ymax;i=i+yinc,j=j+1) {
reciprocals_a[j]=0; // x-values at zero reciprocals_b[j]=1/i; // reciprocals of y-axis major tick values reciprocals_c[j]=i; // y-axis data points at major tick values
// derive text labels from reciprocal values with 1 decimal point precision reciprocals_d[j]=$(reciprocals_b[j],.1);
};
// clear further rows of x and y data points // to avoid plotting results left from previous calculations
mark -m reciprocals_a -b j -e reciprocals!wks.nRows; mark -m reciprocals_c -b j -e reciprocals!wks.nRows; I tried to use the layer.axis.firstTick property to obtain the value of the first tick label but this always seemed to return zero. Any comments on this?
Anyway, this seems to have solved the problem so thanks for the help. I've been meaning to start learning LabTalk programing for some time so this has been a very useful exercise!
Cheers,
Ian.
|
 |
|
|
greg
USA
1380 Posts |
Posted - 05/02/2001 : 10:21:06 AM
|
Origin does not write to the 'First Tick' text box (that I know of) so that would be user-supplied. For example, it's used to 'shift' tick marks from
0, 5, 10, 15, etc.
to
1, 6, 11, 16, etc.
by setting the First Tick to 1 with
layer.x.firsttick = 1
|
 |
|
| |
Topic  |
|
|
|