Алгоритм для “хороших” интервалов линии сетки на графике

Я полностью отключил MAVEN и Spring. И мне пришлось добавить следующие банки для правильной работы моей среды.

  • spring-aop-4.0.3.RELEASE.jar
  • spring-beans-4.0.3 .RELEASE.jar (трудно найти это исправление, другие org.springframework & lt; 3.versions> просто не работают.
  • spring-context-4.0.3.RELEASE.jar
  • spring-core-4.0.3.RELEASE.jar
  • spring-expression-4.0.3.RELEASE.jar
  • spring-web-4.0.3.RELEASE.jar
  • spring-webmvc-4.0.3.RELEASE.jar
  • jstl-1.2.jar

Хуже всего было jstl-api-1.2.jar и javax-servlet.jsp.jst-api-1.2.1.jar Они просто не работали.

`jstl-1.2.jar работал хорошо.

61
задан cletus 12 December 2008 в 02:07
поделиться

5 ответов

CPAN обеспечивает реализацию здесь (см., что источник связывается)

См. также алгоритм Метки для оси графика

к вашему сведению с Вашими демонстрационными данными:

  • Клен: Min=8, Max=74, Labels=10,20.., 60,70, Ticks=10,12,14.. 70,72
  • MATLAB: Min=10, Max=80, Labels=10,20.., 60,80
9
ответ дан Community 7 November 2019 в 13:46
поделиться

Другая идея состоит в том, чтобы иметь диапазон оси быть диапазоном значений, но поместить метки в соответствующее положение.. т.е. для 7 - 22 сделайте:

[- - - | - - - - | - - - - | - - ]
       10        15        20

Что касается выбора интервала галочки, я предложил бы любое количество формы 10^x * я / n, где я < n, и 0 < n < 10. Генерируйте этот список и отсортируйте их, и можно найти наибольшее число меньшим, чем value_per_division (как в adam_liss) использование двоичного поиска.

1
ответ дан FryGuy 7 November 2019 в 13:46
поделиться

Я использую следующий алгоритм. Это подобно другим, отправленным здесь, но это - первый пример в C#.

public static class AxisUtil
{
    public static float CalcStepSize(float range, float targetSteps)
    {
        // calculate an initial guess at step size
        var tempStep = range/targetSteps;

        // get the magnitude of the step size
        var mag = (float)Math.Floor(Math.Log10(tempStep));
        var magPow = (float)Math.Pow(10, mag);

        // calculate most significant digit of the new step size
        var magMsd = (int)(tempStep/magPow + 0.5);

        // promote the MSD to either 1, 2, or 5
        if (magMsd > 5)
            magMsd = 10;
        else if (magMsd > 2)
            magMsd = 5;
        else if (magMsd > 1)
            magMsd = 2;

        return magMsd*magPow;
    }
}
14
ответ дан Drew Noakes 7 November 2019 в 13:46
поделиться

Я сделал это со своего рода методом грубой силы. Во-первых, выясните максимальное количество меток, можно вписаться в пространство. Разделите общий диапазон значений количеством галочек; это минимум интервал галочки. Теперь вычислите, этаж логарифма базируются 10, чтобы получить величину галочки и разделиться на это значение. Необходимо закончить с чем-то в диапазоне 1 - 10. Просто выберите круглое число, больше, чем или равный значению, и умножьте его на логарифм, вычисленный ранее. Это - Ваш заключительный интервал галочки.

Пример в Python:

import math

def BestTick(largest, mostticks):
    minimum = largest / mostticks
    magnitude = 10 ** math.floor(math.log(minimum, 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

Редактирование: Вы свободны изменить выбор "хороших" интервалов. Один комментатор, кажется, неудовлетворен выборами, если, потому что фактическое количество галочек может быть до 2.5 раз меньше, чем максимум. Вот небольшая модификация, которая определяет таблицу для хороших интервалов. В примере я развернул выборы так, чтобы количество галочек не было меньше, чем 3/5 максимума.

import bisect

def BestTick2(largest, mostticks):
    minimum = largest / mostticks
    magnitude = 10 ** math.floor(math.log(minimum, 10))
    residual = minimum / magnitude
    # this table must begin with 1 and end with 10
    table = [1, 1.5, 2, 3, 5, 7, 10]
    tick = table[bisect.bisect_right(table, residual)] if residual < 10 else 10
    return tick * magnitude
34
ответ дан Mark Ransom 7 November 2019 в 13:46
поделиться

Существует 2 части к проблеме:

  1. Определяют порядок величины, включенный, и
  2. Раунд к чему-то удобному.

можно обработать первую часть при помощи логарифмов:

range = max - min;  
exponent = int(log(range));       // See comment below.
magnitude = pow(10, exponent);

Так, например, если Ваш диапазон от 50 - 1200, экспонента равняется 3, и величина 1000.

Тогда соглашение со второй частью путем решения, сколько подразделений Вы хотите в своей сетке:

value_per_division = magnitude / subdivisions;

Это - грубое вычисление, потому что экспонента была усеченной к целому числу. Можно хотеть настроить вычисление экспоненты для обработки граничных условий лучше, , например, путем округления вместо того, чтобы брать int(), если Вы заканчиваете со слишком многими подразделениями.

29
ответ дан Adam Liss 7 November 2019 в 13:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: