选择一个有吸引力的线性比例为图形的Y轴线性、比例为、吸引力、图形

2023-09-10 23:23:42 作者:3分之弍。﹪

我写了一下code显示栏(或线)图中我们的软件。一切都会好的。多数民众赞成让我为难的事情是标签Y轴。

主叫方可以告诉我,他们是如何细致想要的Y比例标记,但我似乎被卡住的正是以一种有吸引力之类的方式来标注。我无法用语言形容有吸引力的,而且很可能你也不能,但我们知道它,当我们看到它,对吗?

因此​​,如果数据点是:

  15,234,140,65,90
 

和用户要求在Y轴10个标签,finagling纸和铅笔一点点来了:

  0,25,50,75,100,125,150,175,200,225,250
 

因此​​,有10那里(不包括0),最后一个延长只是超出了最高值(234< 250),这是一个好增加25只。如果他们要求8张,30个增量看起来会是不错的:

  0,30,60,90,120,150,180,210,240
 
数学之美 燃烧我的卡路里 饮食中隐藏的线性代数

九本来是棘手。也许只是使用了8或10,并呼吁它足够近会好起来的。什么时候做的一些观点是否定?

我可以看到Excel的铲球这个问题很好。

有谁知道一个通​​用算法(甚至有些蛮力是好的)解决呢?我没有迅速做到这一点,但它应该很好看。

解决方案

啊,我很久以前Ø编写了涵盖这很好的图形模块。挖灰色质量得到如下:

确定下限和上限的数据。 (请注意特殊的情况下,其中的下限=上限! 在分割范围内进入所需的蜱数量。 圆形刻度范围达到很好的金额。 调整下和上相应的约束。

让我们把你的例子:

  15,234,140,65,90,10滴答
 

下限= 15 上限= 234 范围= 234-15 = 219 在刻度范围= 21.9。这应该是25.0 在新下界= 25 *轮(15/25)= 0 在新的上限= 25 *轮(1 +二十五分之二百三十五)= 250

因此​​范围= 0,25,50,......,225250

您可以通过以下步骤漂亮的勾号范围:

由10 ^ x满足的结果在0.1和1.0在于(包括0.1不含1)。除法 相应的翻译: 0.1 - > 0.1 < = 0.2 - > 0.2 < = 0.25 - > 0.25 < = 0.3 - > 0.3 < = 0.4 - > 0.4 < = 0.5 - > 0.5 < = 0.6 - > 0.6 < = 0.7 - > 0.7 < = 0.75 - > 0.75 < = 0.8 - > 0.8 < = 0.9 - > 0.9 < = 1.0 - > 1.0 乘以10 ^ x的。

在这种情况下,21.9通过10 ^ 2分频以获得0.219。这为< = 0.25,所以我们现在有0.25。 10 ^ 2这给25相乘。

让我们来看看同样的例子有8蜱:

  15,234,140,65,90,8蜱
 

下限= 15 上限= 234 范围= 234-15 = 219 在刻度范围= 27.375 除以10 ^ 2为0.27375,转化为0.3,这给30(10 ^ 2相乘)。 在新下界= 30 *轮(15/30)= 0 在新的上限= 30 *轮(1 +三十○分之二百三十五)= 240

这给你所要求的结果; - 。)

------添加人KD ------

下面是code,可实现该算法,而不使用查找表,等等...

 双范围= ...;
INT计时单位计数= ...;
双unroundedTickSize =范围/(计时单位计数-1);
双X = Math.ceil(Math.log10(unroundedTickSize)-1);
双pow10x = Math.pow(10,X);
双roundedTickRange = Math.ceil(unroundedTickSize / pow10x)* pow10x;
返回roundedTickRange;
 

一般而言,蜱虫的数量,包括底部打勾,因此实际y轴段少了一个比蜱的数量。

I'm writing a bit of code to display a bar (or line) graph in our software. Everything's going fine. The thing that's got me stumped is labeling the Y axis.

The caller can tell me how finely they want the Y scale labeled, but I seem to be stuck on exactly what to label them in an "attractive" kind of way. I can't describe "attractive", and probably neither can you, but we know it when we see it, right?

So if the data points are:

   15, 234, 140, 65, 90

And the user asks for 10 labels on the Y axis, a little bit of finagling with paper and pencil comes up with:

  0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250

So there's 10 there (not including 0), the last one extends just beyond the highest value (234 < 250), and it's a "nice" increment of 25 each. If they asked for 8 labels, an increment of 30 would have looked nice:

  0, 30, 60, 90, 120, 150, 180, 210, 240

Nine would have been tricky. Maybe just have used either 8 or 10 and call it close enough would be okay. And what to do when some of the points are negative?

I can see Excel tackles this problem nicely.

Does anyone know a general-purpose algorithm (even some brute force is okay) for solving this? I don't have to do it quickly, but it should look nice.

解决方案

O my, long time ago O have written a graph module that covered this nicely. Digging in the grey mass gets the following:

Determine lower and upper bound of the data. (Beware of the special case where lower bound = upper bound! Divide range into the required amount of ticks. Round the tick range up into nice amounts. Adjust the lower and upper bound accordingly.

Lets take your example:

15, 234, 140, 65, 90 with 10 ticks

lower bound = 15 upper bound = 234 range = 234-15 = 219 tick range = 21.9. This should be 25.0 new lower bound = 25 * round(15/25) = 0 new upper bound = 25 * round(1+235/25) = 250

So the range = 0,25,50,...,225,250

You can get the nice tick range with the following steps:

divide by 10^x such that the result lies between 0.1 and 1.0 (including 0.1 excluding 1). translate accordingly: 0.1 -> 0.1 <= 0.2 -> 0.2 <= 0.25 -> 0.25 <= 0.3 -> 0.3 <= 0.4 -> 0.4 <= 0.5 -> 0.5 <= 0.6 -> 0.6 <= 0.7 -> 0.7 <= 0.75 -> 0.75 <= 0.8 -> 0.8 <= 0.9 -> 0.9 <= 1.0 -> 1.0 multiply by 10^x.

In this case, 21.9 is divided by 10^2 to get 0.219. This is <= 0.25 so we now have 0.25. Multiplied by 10^2 this gives 25.

Lets take a look at the same example with 8 ticks:

15, 234, 140, 65, 90 with 8 ticks

lower bound = 15 upper bound = 234 range = 234-15 = 219 tick range = 27.375

Divide by 10^2 for 0.27375, translates to 0.3, which gives (multiplied by 10^2) 30.

new lower bound = 30 * round(15/30) = 0 new upper bound = 30 * round(1+235/30) = 240

Which give the result you requested ;-).

------ Added by KD ------

Here's code that achieves this algorithm without using lookup tables, etc...:

double range = ...;
int tickCount = ...;
double unroundedTickSize = range/(tickCount-1);
double x = Math.ceil(Math.log10(unroundedTickSize)-1);
double pow10x = Math.pow(10, x);
double roundedTickRange = Math.ceil(unroundedTickSize / pow10x) * pow10x;
return roundedTickRange;

Generally speaking, the number of ticks includes the bottom tick, so the actual y-axis segments are one less than the number of ticks.