我需要制作一个具有优化y轴最大值的图表。
我目前制作图表的方法只是使用所有图表的最大值,然后将其除以 10,并将其用作网格线。我没写。
更新说明:这些图表已更改。一旦我修复了代码,我的动态图就开始工作了,这让这个问题变得荒谬(因为示例中不再有任何错误)。我已经用静态图像更新了这些,但有些答案引用了不同的值。记住这一点。 到目前为止,2 月份有 12003 到 14003 个呼入电话。信息丰富,但丑陋。
我想避免看起来像猴子的图表想出了y轴数字。
使用 Google 图表 API 会有所帮助,但仍然不是我想要的。 数字很干净,但 y 值的顶部始终与图表上的最大值相同。该图表的范围从 0 到 1357。我需要计算出 1400 的正确值,但有问题。
我在这里加入了rbobby对“好”数字的定义,因为它很好地解释了它。
- “不错”的数字是具有 3 个或更少非零数字的数字(例如 1230000)
- 一个“好”的数字与零数字具有相同或少数几个非零数字(例如,1230 不好,1200 好)
- 最好的数字是 3 个零的倍数(例如“1,000”、“1,000,000”)
- 第二好的数字是 3 个零加上 2 个零的复数(例如“1,500,000”、“1,200”)
解决方案
我找到了使用 Mark Ransom 想法的修改版本来获得我想要的结果的方法。
首先,Mark Ransom 的代码在给定刻度数时确定刻度之间的最佳间距。有时,这个数字最终会是图表上最高值的两倍多,具体取决于您想要多少条网格线。
我正在做的是用 5、6、7、8、9 和 10 条网格线(刻度线)运行 Mark 的代码,以找出其中最低的。值为 23 时,图表高度变为 25,网格线位于 5、10、15、20 和 25 处。值为 26 时,图表高度为 30,网格线位于 5、10 , 15, 20, 25, 和 30。网格线之间的间距相同,但数量更多。
因此,这里是复制 Excel 所做的一切以制作精美图表的步骤。
- 暂时将图表的最高值提高 5% 左右(这样图表的最高点和图表区域的顶部之间总是有一些空间。我们希望 99.9 向上舍入到 120)
- 找到 5、6、7、8、9 和 10 条网格线的最佳网格线位置。
- 从这些数字中选出最低的。记住获得该值所需的网格线数。
- 现在您有了最佳图表高度。线/条永远不会与图表顶部对接,并且您拥有最佳的刻度数。
PHP:
function roundUp($maxValue){
$optiMax = $maxValue * 2;
for ($i = 5; $i <= 10; $i++){
$tmpMaxValue = bestTick($maxValue,$i);
if (($optiMax > $tmpMaxValue) and ($tmpMaxValue > ($maxValue + $maxValue * 0.05))){
$optiMax = $tmpMaxValue;
$optiTicks = $i;
}
}
return $optiMax;
}
function bestTick($maxValue, $mostTicks){
$minimum = $maxValue / $mostTicks;
$magnitude = pow(10,floor(log($minimum) / log(10)));
$residual = $minimum / $magnitude;
if ($residual > 5){
$tick = 10 * $magnitude;
} elseif ($residual > 2) {
$tick = 5 * $magnitude;
} elseif ($residual > 1){
$tick = 2 * $magnitude;
} else {
$tick = $magnitude;
}
return ($tick * $mostTicks);
}
Python:
import math
def BestTick(largest, mostticks):
minimum = largest / mostticks
magnitude = 10 ** math.floor(math.log(minimum) / math.log(10))
residual = minimum / magnitude
if residual > 5:
tick = 10 * magnitude
elif residual > 2:
tick = 5 * magnitude
elif residual > 1:
tick = 2 * magnitude
else:
tick = magnitude
return tick
value = int(input(""))
optMax = value * 2
for i in range(5,11):
maxValue = BestTick(value,i) * i
print maxValue
if (optMax > maxValue) and (maxValue > value + (value*.05)):
optMax = maxValue
optTicks = i
print "\nTest Value: " + str(value + (value * .05)) + "\n\nChart Height: " + str(optMax) + " Ticks: " + str(optTicks)