曲线坐标轴范围及刻度的自适应算法综述

摘自:http://www.cnblogs.com/pengcl/p/3278388.html

由于工作原因,需要画图表,但在图表的该度的取值上就出现了问题,但现在关于图表的控件已经很多了,那应该也有成熟的算法了,经过在网上努力寻找前人们是足迹,算给我找到了这编文章,问题总算解决了!!!---故记。

(1)步长规范化是关键

一般地,我们在标定坐标轴时,给出的参数是:起点、终点和刻度数,因为我们程序设计人员对在一个多大的区域面积内绘制多少个刻度比较美观有直观感觉,相反,而对多大步长则印象较浅。当然,知道刻度数和起点与终点值求步长是很容易的,如下式:

CorStep=(CorMax-CorMin)/CorNumber

式中,CorMax、CorMin、CorNumber分别对应起点、终点和刻度数。步长求出后。我们只要将步长求以lO为底的对数,即可获得步长的数量级,见下式:

Temp=Log(corStep)/Log(10)

或者

Temp=Log(CorStep)/Log(10)+1

式中,Log代表自然对数。至于取哪个公式,需要根据CorStep是否是lO的整数次幂而定。

进而将步长其规范化到0到1的范围内,方法如下:

NewCopStep=CorStep/(10^Temp)

式中,符号“^”代表取幂的意思。

然后根据新的步长取值范围,将新的取值定位在:0.1、O.2、0.25、0.5、1几个常规步长上,称为StardardStep.最后,再根据数量级将规范的步长恢复到本来的数量级上,见下式:

FinalStep=StardardStp*Temp

(2)起点的规范化

一般说来.我们的起点应该是小于等于原来的起点,同时,起点坐标是步长的整数倍比较符合人们的习惯。这一点容易做到,见下式:

NewCorMin=(Int(CorMin/FinalStep))*FinalStep

其中,Int是取整函数。

(3)终点的规范化

按惯例,我们的终点应该是大于等于原来的终点,同样,终点坐标是步长的整数倍比较符合人们的习惯,见下式:

NewCorMax=(Int(CorMax/FinalStep)+1)+FinalStep

其中,Int是取整函数。

(4)最后的修正我们按上面的公式确定完参数后,新确定的步长、起点、终点值有可能使得刻度数与原来刻度数不等。这里是否需要调整呢?如果需要,我们应该如何调整呢?笔者认为,如果新算得的刻度数大于等于原来设定的刻度数,就不应该调整了。如果新算得的刻度数小于原来设定的刻度数,就应该将其调整为原来的刻度数。同时,在步长不动的情况下,分别将起点与终点进行再次修正。

下面是对应的程序:

注:源文为VB代码,由于工作需要,转为javascript代码。

function standard(cormax,cormin,cornumber){
var tmpmax,tmpmin, corstep,tmpstep,tmpnumber,temp,extranumber;
if(cormax<=cormin)
return ;
corstep=(cormax-cormin)/cornumber;
if(Math.pow(10,parseInt(Math.log(corstep)/Math.log(10)))==corstep){
temp = Math.pow(10,parseInt(Math.log(corstep)/Math.log(10)));
}else{
temp = Math.pow(10,(parseInt(Math.log(corstep)/Math.log(10))+1));
}
tmpstep = (corstep/temp).toFixed(6);
//选取规范步长
if(tmpstep>=0&&tmpstep<=0.1){
tmpstep = 0.1;
}else if(tmpstep>=0.100001&&tmpstep<=0.2){
tmpstep = 0.2;
}else if(tmpstep>=0.200001&&tmpstep<=0.25){
tmpstep = 0.25;
}else if(tmpstep>=0.250001&&tmpstep<=0.5){
tmpstep = 0.5
}else{
tmpstep = 1;
}
tmpstep = tmpstep * temp;
if(parseInt(cormin/tmpstep)!=(cormin/tmpstep)){
if(cormin<0){
cormin = (-1) * Math.ceil(Math.abs(cormin/tmpstep))*tmpstep;
}else{
cormin = parseInt(Math.abs(cormin/tmpstep))*tmpstep;
}

}
if(parseInt(cormax/tmpstep)!=(cormax/tmpstep)){
cormax = parseInt(cormax/tmpstep+1)*tmpstep;
}
tmpnumber = (cormax-cormin)/tmpstep;
if(tmpnumber<cornumber){
extranumber = cornumber - tmpnumber;
tmpnumber = cornumber;
if(extranumber%2 == 0){
cormax = cormax + tmpstep*parseInt(extranumber/2);
}else{
cormax = cormax + tmpstep*parseInt(extranumber/2+1);
}
cormin = cormin - tmpstep*parseInt(extranumber/2);
}
cornumber = tmpnumber;
return [cormax,cormin,cornumber];
}

                                 ---------------文章摘抄于《坐标轴刻度的规范化标定处理》

转自:http://blog.sciencenet.cn/blog-548663-710759.html

数据作图时,纵横坐标轴刻度范围及刻度值的取法,很大程度上取决于数据的分布。对某一组数据,我们很容易就能知道如何选取这些值才能使图画得漂亮。但是要想找到一个通用的算法,用以对任意分布的数据决定这些值,并不是一件容易的事。下面是我在网上找到的一些作法,权作备份。 

    一篇论文,提出了一种稍嫌复杂,但效果很好的方法,并与目前常用的几种方法作了对比。学院派的典型解决模式:
An Extension of Wilkinson’s Algorithm for Positioning Tick Labels on Axes
http://vis.stanford.edu/papers/tick-labels

    最早或许也是最简单的一种解决方法。工程师的解决模式,源码:
Heckbert
算法,Graphics Gems 1
http://tog.acm.org/resources/GraphicsGems/gems/Label.c

    中国程序员的解决方案:
求算法:图表控件,如何确定坐标轴的范围和刻度?
http://bbs.csdn.net/topics/340165746

http://yun.baidu.com/xcloud/csdn/pan/share/link?shareid=2328597457&uk=1127608729

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在Matlab中,可以使用`xlim`和`ylim`函数来修改坐标轴范围,同时可以使用`xticks`和`yticks`函数来修改坐标轴刻度。例如,如果要将x轴的范围设置为0到10,y轴范围设置为-5到5,并将x轴的刻度设置为0到2之间的整数,y轴刻度设置为-5到5之间的整数,可以使用以下代码: ```matlab xlim([0, 10]); ylim([-5, 5]); xticks(0:2:10); yticks(-5:5); ``` 其中,`xticks`和`yticks`函数的参数是一个向量,表示要在坐标轴上显示的刻度值。在上面的例子中,`xticks(0:2:10)`表示将x轴上的刻度设置为0、2、4、6、8和10。`yticks(-5:5)`表示将y轴上的刻度设置为-5、-4、-3、-2、-1、0、1、2、3、4和5。这些函数也可以在绘制图形之前或之后调用。 如果要修改坐标轴范围刻度,并同时设置刻度标签的格式,可以使用`xtickformat`和`ytickformat`函数。例如,如果要将x轴的范围设置为0到10,y轴范围设置为-5到5,并将x轴的刻度设置为0到2之间的整数,y轴刻度设置为-5到5之间的整数,并将刻度标签设置为两位小数,可以使用以下代码: ```matlab xlim([0, 10]); ylim([-5, 5]); xticks(0:2:10); yticks(-5:5); xtickformat('%.2f'); ytickformat('%.2f'); ``` 其中,`xtickformat`和`ytickformat`函数的参数是一个格式化字符串,表示要在刻度标签中显示的格式。在上面的例子中,`'%.2f'`表示使用两位小数来显示刻度标签。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值