为图形的 Y 轴选择有吸引力的线性比例 [英] Choosing an attractive linear scale for a graph's Y Axis

查看:21
本文介绍了为图形的 Y 轴选择有吸引力的线性比例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一些代码来在我们的软件中显示条形图(或折线图).一切都很顺利.让我难住的事情是标记 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.

来电者可以告诉我他们希望 Y 刻度标记的精细程度,但我似乎被困在以有吸引力"的方式标记它们的确切内容上.我无法形容有吸引力",您可能也无法形容,但我们看到它就知道了,对吗?

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?

所以如果数据点是:

   15, 234, 140, 65, 90

并且用户要求在 Y 轴上有 10 个标签,稍微用纸和铅笔搞定:

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

所以那里有 10 个(不包括 0),最后一个超出最高值(234 < 250),这是一个不错"的增量,每个 25.如果他们要求 8 个标签,增加 30 个看起来不错:

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

九个会很棘手.也许只是使用了 8 或 10 并称其足够接近就可以了.当某些点为负时该怎么办?

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?

我可以看到 Excel 很好地解决了这个问题.

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.

推荐答案

很久以前我写了一个图形模块,很好地涵盖了这一点.挖掘灰色块得到以下结果:

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

  • 确定数据的下限和上限.(注意下限 = 上限的特殊情况!
  • 将范围划分为所需的刻度数.
  • 将刻度范围四舍五入为合适的数量.
  • 相应地调整下限和上限.

让我们举个例子:

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

  1. 下限 = 15
  2. 上限 = 234
  3. 范围 = 234-15 = 219
  4. 刻度范围 = 21.9.这应该是 25.0
  5. 新的下限 = 25 * round(15/25) = 0
  6. 新的上限 = 25 * round(1+235/25) = 250

所以范围 = 0,25,50,...,225,250

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

您可以通过以下步骤获得合适的刻度范围:

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

  1. 除以 10^x 使结果介于 0.1 和 1.0 之间(包括 0.1 不包括 1).
  2. 相应地翻译:
    • 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

在这种情况下,21.9 除以 10^2 得到 0.219.这是 <= 0.25 所以我们现在有 0.25.乘以 10^2 得到 25.

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.

让我们看一下有 8 个刻度的同一个例子:

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

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

  1. 下限 = 15
  2. 上限 = 234
  3. 范围 = 234-15 = 219
  4. 刻度范围 = 27.375
  1. lower bound = 15
  2. upper bound = 234
  3. range = 234-15 = 219
  4. tick range = 27.375
  1. 除以 10^2 为 0.27375,转换为 0.3,得到(乘以 10^2)30.

  • 新的下限 = 30 * round(15/30) = 0
  • 新上限 = 30 * round(1+235/30) = 240
  • 给出你要求的结果;-)

    Which give the result you requested ;-).

    ------ 由 KD 添加------

    ------ 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;
    

    一般来说,tick数量包括底部tick,所以实际y轴段比tick数量少1.

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

    这篇关于为图形的 Y 轴选择有吸引力的线性比例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆