T O P I C R E V I E W |
jdf726 |
Posted - 02/08/2019 : 06:37:06 AM Origin Ver. and Service Release (Select Help-->About Origin): 2018 pro 64 bit Operating System: Win7 64
I have an intermittent problem with overlapping x axis labels in programmatically created plots.
I have an origin C script that creates plots from a template, but the size of the X axis parameter could vary widely (it could be a phase in degree '120', or a voltage with mV resolution '0.575').
While the limits are controlled by the plotted data, the spacing of the labels is presumably being automatically sorted by Origin's 'make a nice axis' algorithm. These routines are normally set to recognise what the most 'natural' spacing would be, in steps of 10, 5, 3, 2 or 1.
This works a lot of the time, my axis might span -0.600 volts to -0.585 volts with three 0.005 V increments, but sometimes it goes horribly wrong, where the labels are too close together and the leading '0' of one label overwrites the trailing digit of the previous one!!! (Sometimes I only realise this is the case when I am presenting the data in a meeting, which is embarrassing!)
I suspect I can write my own 'fix axis labels' labtalk script that tries to work out what the most sensible increment would be, but I wonder if there is already some built-in feature that should always avoid 'label collision'!
One reason that I am posting is that perhaps this feature actually exists, and I am somehow accidentally undermining it with something weird in my plot template or formatting commands.
J. |
11 L A T E S T R E P L I E S (Newest First) |
jdf726 |
Posted - 02/22/2019 : 2:38:44 PM It is not a complete solution (it is only X-axis) but I modified the X-function to apply the the x-axis fix to on all layers. You can set a negative number of target steps to toggle the different rounding conditions that people suggested.
void NiceX(const int& steps) { GraphLayer gll = Project.ActiveLayer(); GraphPage gp = gll.GetPage(); foreach(GraphLayer gl in gp.Layers) { Axis axesX = gl.XAxis; double x; x = (axesX.Scale.To.dVal - axesX.Scale.From.dVal)/abs(steps); double exponent = floor(log10(x)); double fraction = x/pow(10,exponent); double niceFraction = 0; bool rnd = (steps>0); if (rnd) { if (fraction < 1.5) niceFraction = 1; else if (fraction < 3) niceFraction = 2; else if (fraction < 7) niceFraction = 5; else niceFraction = 10; } else { if (fraction <= 1) niceFraction = 1; else if (fraction <= 2) niceFraction = 2; else if (fraction <= 5) niceFraction = 5; else niceFraction = 10; } double inc = niceFraction*pow(10,exponent); axesX.Scale.Value.dVal = inc; // Increment value }
} |
yuki_wu |
Posted - 02/19/2019 : 10:38:45 PM Hi J,
Sorry for the late reply.
It took us a few days to discuss and think more about this question. We might do something to improve this issue in the future.
Also, you could try to specify a minus value for the major tick numbers, so as to make the tick label numbers rounded-up and you could get the easy-to-read labels. In case of negative major tick numbers, Origin will try to get the best range to make sure the tick labels are integers and the total tick number will try to be closest to the absolute value which was set, but not exactly the same.
Regards, Yuki
OriginLab
|
jdf726 |
Posted - 02/13/2019 : 1:45:34 PM Hi Yuki, thank you for your patience ;-)
I know you can set these things manually, but to do so, I would have to re-open/reimport with an explicit increment chosen by the user.
The point is to AUTOMATICALLY create a beautiful Origin axis, with large enough labels that they are legible (even when printed out ~8+ plots per page) while using 'nice' intervals 0.1, 0.05, 0.02 etc.
This is 'almost' what Origin does out of the box...unless like me you have an unusually large labels.
What you have reminded me is that you can set (and indeed FORCE) the number of major ticks, so you could just have the end points (and maybe the middle) of the axis be major ticks (and the labels would NEVER overlap)
The trouble is that this bypasses the 'nice increments', and you will end up with an axis that is hard to read. I just checked and with -0.621 to -0.584 with 4 major ticks ends up being -0.612, -0.6, -0.588, i.e. the increment is set to something weird ~0.012.
In contrast, the 'NiceSpacing' X-function I posted...
NiceSpacing((layer.x1.to-layer.x1.from)/5,b); layer.x1.inc = b;
Gives -0.62, -0.61, -0.6, -0.59, -0.58, which is nice, but close to the maximum number of labels you I fit on.
NiceSpacing((layer.x1.to-layer.x1.from)/3,b); layer.x1.inc = b;
Gives -0.62, -0.6, 0.58, which is safer.
You could also go and hide every Nth label as you suggest (which is also a nice idea), but if you don't a priori know how many labels is the 'correct number' this might make things worse (if you end up with only 2 and then hide 1 you are stuffed!)
Part of my question was 'Does Origin even realise that the labels are overlapping?!'. If it does, then it could easily re-evaluate the automatic spacing as in my suggestion above and fix it. Call it a feature suggestion!
Actually, I have observed many times that you can sometimes get just ONE labeled tick! That is also unacceptable...when this happens you have to re-imported the data and reprocess this to fix it.
In practise, I plan to put the 'axis fixing' function into the import script to avoid both problems.
Kind regards
J.
|
yuki_wu |
Posted - 02/12/2019 : 10:24:35 PM Hi J,
1. Yes, Origin will calculate the increment and set it for the axis automatically if user don’t specify it.
2. Ticks include major ticks and minor ticks. We could show the major tick labels and hide the minor tick labels. This is also the default setting of Origin. For example, for the range 0.521 to 0.562, we could set the major ticks by increment = 0.005 while the minor ticks by count = 10.
3. In fact, Origin can control the number of ticks for each axis. Just like I mentioned earlier, double click to open the axis dialog, go to Scale tab, and select By Counts in Type for Major Ticks, or use LabTalk script layer.axis.majorTicks. Origin can even control the position of ticks. Please refer to my previous answer.
4. I don’t think this is a bug. It is common to see the closely ticks with a long label, but there are a lot of ways to solve this issue:
a. Rotate the tick label or choose a smaller font size for the label b. Re-arrange the ticks, use fewer major ticks and more minor ticks and show the major ticks only. c. Show specified ticks only. (Select Max & Min form Major Ticks Type dropdown in Scale Tab, set the number for minor ticks, then go to Tick Labels tab: Minor Tick Labels and select Show at Specified Indices Only) d. …
Regards, Yuki
OriginLab
|
jdf726 |
Posted - 02/12/2019 : 03:16:56 AM Sorry Yuki, I will explain.
We use a script to import data in batches. Every day I might import ~1000 files, every ~100 of which correspond to a 2D dataset. This 2D dataset is assembled into various matrices and then saved, plotted and the plots exported to disk as an image (automatically).
The x-axis range on these plots picks up the maximum and the minimum automatically, but what sets the increment on the X-axis? I think it is automatically set by Origin. This sometimes works nicely, sometimes not. As in the pictures I showed, there can be bad 'label clash'.
The solutions that emerged were
1. Add a MANUAL increment setting to the import script (e.g. forcing a 5mV increment). This forces the user to think during import how the decision they made on scan range will be manifest in the plotting stage due to the number of digits in the label (how should the range -0.562 to -0.521 be divided?)
2. Some built-in Origin setting that controls the number of ticks that are put on the axis? This exists in the 'Options dialog'. This is GLOBAL preference for the preferred number of ticks, and might be the answer, it's just that I had to set it to a very small number (3) and it would presumably affect ALL plot axes.
3. Use a targeted script that takes over the increment setting using the fairly well-known 'rounding logic', biased towards fewer labels.
The third one enables me to both 'locally' and 'automatically' cut back on labels, at the expense of adding another function and is thus a good solution.
I did wonder whether Origin might already calculate where the boundary of labels overlap, but perhaps not. I would hesitate to call it a 'bug'...maybe my settings on that axis are a little unusual.
J. |
yuki_wu |
Posted - 02/11/2019 : 10:48:04 PM Hi J,
I am sorry that I might not understand your question fully.
I feel a little bit confused about your question. I mean we can control the ticks label via several methods. In GUI, we can double click to open the axis dialog, go to Scale tab, and select By Counts in Type for Major Ticks. This options can help to set the total major tick displayed on the axis. Or we could select By Custom Positions to specify the position of major tick.
In LabTalk, we could use:
layer.axis.majorTicks
and
layer.axis.TicksByData$
https://www.originlab.com/doc/LabTalk/ref/Layer-Axis-obj
Regards, Yuki OriginLab
|
jdf726 |
Posted - 02/11/2019 : 5:28:56 PM OK, so I got 5 mins to transcribe the 'natural rounding' thing into an X-function.
Then you can call
NiceSpacing((layer.x1.to-layer.x1.from)/6,b); layer.x1.inc = b
Where the denominator (6) controls roughly how many ticks you want. This fixes some of the examples I already had of label clash.
Here is the X-function. I haven't worked out what the 'round' switch does so this is a constant.
void NiceSpacing(const double& x, double& inc) { double exponent = floor(log10(x)); double fraction = x/pow(10,exponent); double niceFraction = 1;
bool rnd =false; if (rnd) { if (fraction < 1.5) niceFraction = 1; else if (fraction < 3) niceFraction = 2; else if (fraction < 7) niceFraction = 5; else niceFraction = 10; } else { if (fraction <= 1) niceFraction = 1; else if (fraction <= 2) niceFraction = 2; else if (fraction <= 5) niceFraction = 5; else niceFraction = 10; } inc = niceFraction*pow(10,exponent); }
|
jdf726 |
Posted - 02/11/2019 : 11:40:40 AM I found this dialog
https://www.originlab.com/doc/Origin-Help/Options-Dialog-Axis-Tab#Max._Number_of_Ticks_Group
and had a go at changing the axis options to a very small number of ticks. I had to set it at '3' and call the 'rescale' command to format one particularly stubborn X-axis to a sensible value. I wonder whether such an extreme setting might have consequences for other axes. |
jdf726 |
Posted - 02/11/2019 : 10:33:05 AM This is the kind of algorithm I mean (here the same code snippet has been converted into a bunch of languages). My hope was to mimic this, but somehow bias it towards having the absolute minimum number of labels to avoid overlap.
https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks |
jdf726 |
Posted - 02/11/2019 : 09:24:42 AM Hi Yuki!
That is an interesting idea and it looks 'cute' in a way ;-) Trouble is that I have a label in that position and I would have to rearrange that (I enclose some pictures).



Here I set the increment manually to something that looks nice, but this may not always be the 'best' increment setting (otherwise I would fix it).
I assume there is already the '10,5,3,2,1' spacing routine in place (so you never get increments of 7!) but that it is just too aggressive in trying to fit too many labels in when each has 4 figures. Does Origin actively detect label clashes?
J. |
yuki_wu |
Posted - 02/10/2019 : 10:46:01 PM Hi J,
I think you could rotate the axis labels to avoid label overlap. For example, this scirpt rotate the x axis label of the active layer:
range ll = !;
ll.x.label.rotate = 45; https://www.originlab.com/doc/LabTalk/ref/Layer-Axis-Label-obj
Regards, Yuki OriginLab
|
|
|