TAChart и логарифмическая шкала

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

TAChart и логарифмическая шкала

Сообщение Boris » 09.06.2011 16:12:23

Понадобилось отобразить в шкалу от 1 до 1e8 в логарифмическом масштабе по основанию 10. Добавляю логарифмический трансформ, и в процессе выполнения получаю переполнение вычислений с ПТ. Вылетает в строке TTAtransformations.pas:630:

Код: Выделить всё
function TLogarithmAxisTransform.GraphToAxis(AX: Double): Double;
begin
  Result := Power(Base, AX);
end;

Оно и понятно, 10 в степени 10000 это многовато. Вполне возможно, что такое решение "в лоб" неправильно, тогда как правильно?
Boris
новенький
 
Сообщения: 17
Зарегистрирован: 22.01.2011 20:45:48

Re: TAChart и логарифмическая шкала

Сообщение Maxizar » 09.06.2011 17:36:26

Boris я возможно не понял суть вопроса, но если вам нужна шкала от 1 до 10^8 (10 в степени 8. )то откуда цифра 10 в степени 10000 ?
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: TAChart и логарифмическая шкала

Сообщение Boris » 09.06.2011 19:09:20

Просто следующая точка в серии это 10000, в выше приведенном коде выполняется power(10, 10000) и возникает ошибка.
Boris
новенький
 
Сообщения: 17
Зарегистрирован: 22.01.2011 20:45:48

Re: TAChart и логарифмическая шкала

Сообщение Padre_Mortius » 09.06.2011 20:03:56

Boris, масштабирование вам поможет решить вашу проблему с отображением таких величин, а вот возведение в степень вам придется писать самому или искать модуль для работы с большими числами
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Re: TAChart и логарифмическая шкала

Сообщение Ask » 10.06.2011 01:23:44

Тут что-то не так.
Какая версия Lazarus? Как добавляются точки?
Работает ли стандартная демка (axistransform, страница "Logarithm"?)
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: TAChart и логарифмическая шкала

Сообщение Boris » 10.06.2011 07:29:11

Версия 0.9.31 (2011-06-08), fpc 2.4.3. Стандартная демо работает, а если сделать логарифмической ось X, то не работает:
Код: Выделить всё
Index: main.lfm
===================================================================
--- main.lfm   (revision 31150)
+++ main.lfm   (working copy)
@@ -225,13 +225,13 @@
             Title.LabelFont.Orientation = 900
             Title.Visible = True
             Title.Caption = 'Left'
-            Transformations = catLog
           end       
           item
             Alignment = calBottom
             Title.Distance = 0
             Title.Visible = True
             Title.Caption = 'Bottom'
+            Transformations = catLog
           end       
           item
             Alignment = calRight
Index: main.pas
===================================================================
--- main.pas   (revision 31150)
+++ main.pas   (working copy)
@@ -146,7 +146,7 @@
   for i := 0 to 50 do begin
     with cfsLog.Extent do
       x := i / 50 * (XMax - XMin) + XMin;
-    clsLogPoints.AddXY(x + Random - 0.5, MyFunc(x) + Random - 0.5);
+    clsLogPoints.AddXY(x + i * 1000, MyFunc(x) + Random - 0.5);
   end;
   FillIndependentSource;
end;
Boris
новенький
 
Сообщения: 17
Зарегистрирован: 22.01.2011 20:45:48

Re: TAChart и логарифмическая шкала

Сообщение Ask » 10.06.2011 10:06:57

Вот, совсем другое дело :-)

Нужно установить
clsLogPoints.AxisIndexX := 1
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: TAChart и логарифмическая шкала

Сообщение Boris » 10.06.2011 10:21:46

Спасибо, все получилось (раньше на эти грабли наступал, но забыл).

Еще один вопрос: можно ли получить такую сетку?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Boris
новенький
 
Сообщения: 17
Зарегистрирован: 22.01.2011 20:45:48

Re: TAChart и логарифмическая шкала

Сообщение Ask » 10.06.2011 12:35:42

Вообще говоря, сетку можно получить любую, указав собственный Source.
Другое дело, что придётся задать значения вручную (ну или написать цикл).
Я как раз сейчас обдумываю доработки, которые нужны, чтобы задавать параметры сетки
более гибко -- идеи приветствуются.
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: TAChart и логарифмическая шкала

Сообщение Boris » 10.06.2011 13:15:33

Образец гибкости (для меня конечно), это gnuplot. Раньше графики делал в нем, сейчас пытаюсь перейти на tachart. Собственно предыдущий вопрос и был задан потому, что включение логарифмической сетки обычно дает результат приведенный выше (пример из gnuplot: http://folk.uio.no/steikr/doc/gnuplot/Kawano/intro/plotexp7.png).
Boris
новенький
 
Сообщения: 17
Зарегистрирован: 22.01.2011 20:45:48

Re: TAChart и логарифмическая шкала

Сообщение Ask » 10.06.2011 13:36:24

Судя по картинке, дело не в гибкости, а в удачных значениях по умолчанию.
(Я, кстати, не совсем понимаю, чем хорошо неравномерное деление второго уровня
при равномерном делении первого уровня).
Хочется дать пользователю возможность управлять размером/количеством интервалов,
подбором "круглых" значений, взаимодействием с изменением масштаба,
и чтобы всё это работало не только в случае логарифмического преобразования.
Вопрос в выборе API.
Какие свойства нужно добавить, с какой семантикой?
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: TAChart и логарифмическая шкала

Сообщение Boris » 10.06.2011 13:52:04

Ask писал(а):Судя по картинке, дело не в гибкости, а в удачных значениях по умолчанию.
(Я, кстати, не совсем понимаю, чем хорошо неравномерное деление второго уровня
при равномерном делении первого уровня).


Это весьма удобно для графиков, в которых вторая ось тоже выражена в логарифмическом масштабе. Кроме того, так легче определять значения малых величин. Например, берем шкалу от 0.01 до 1000, если просто отобразить ее, то понять что творится в левой половине графика будет весьма затруднительно, а так есть сетки для интервалов 0.01..0.1, 0.1..1, 1..10, 10..100 и 100..1000. Некоторые соображения есть также здесь: http://en.wikipedia.org/wiki/Logarithmic_scale#Log-log_plots.

В данном случае, вид сетки и метки интервалов определяются основанием логарифма. Если требуется сохранить совместимость с предыдущим поведением, то кроме параметра Base можно добавить логический DisplayDecades.
Boris
новенький
 
Сообщения: 17
Зарегистрирован: 22.01.2011 20:45:48

Re: TAChart и логарифмическая шкала

Сообщение Ask » 10.06.2011 14:03:12

Boris писал(а): легче определять значения малых величин

Хм. Если вторичные деления сделать равномерными, то понять, что в левой части графика, будет ещё легче, нет?

Boris писал(а): вид сетки и метки интервалов определяются основанием логарифма

Непонятно, как из основания 10 получить количество вторичных меток (в данном случае восемь)?
Что, если основание, скажем, e (натуральный логарифм)?

Boris писал(а):логический DisplayDecades.

Что он должен делать?
Ask
постоялец
 
Сообщения: 163
Зарегистрирован: 25.12.2008 03:51:37

Re: TAChart и логарифмическая шкала

Сообщение Boris » 10.06.2011 14:27:20

Ask писал(а):Хм. Если вторичные деления сделать равномерными, то понять, что в левой части графика, будет ещё легче, нет?


Нет, в этом случае вид графика существенно изменится, и там где была прямая, появятся волны.

Ask писал(а):Непонятно, как из основания 10 получить количество вторичных меток (в данном случае восемь)?
Что, если основание, скажем, e (натуральный логарифм)?


Для основания 10, основная шкала всегда состоит из ряда степеней 10 (включая отрицательные, если нужно). Вторичная сетка всегда идет по ряду 2-9 умноженному на значение предыдущей основной метки. Т.е для интервала 0.1..1 ряд будет 0.2,0,3,0,4... Можно, в принципе, указать число желаемых сабинтервалов - 10, 5, но это уже косметика.

Если основание логарифма не равно 10, то применяется такой алгоритм как есть сейчас.

Ask писал(а):
Boris писал(а):логический DisplayDecades.

Что он должен делать?


Включать отображение сабинтервалов - исключительно для целей совместимости.
Boris
новенький
 
Сообщения: 17
Зарегистрирован: 22.01.2011 20:45:48

Re: TAChart и логарифмическая шкала

Сообщение Boris » 19.06.2011 07:05:17

Нашел простое решение: определяем ListSource с рядами 0.1,0.2..0.9,1,2..9,10,20..90 и т.д, ставим его в качестве источника для меток оси и добавляем логарифмическое преобразование. Единственный недостаток - декадные метки показываются не всегда: 700,900,2000, тогда как должно было быть 700,1000,2000, т.к. декады имеют приоритет.
Boris
новенький
 
Сообщения: 17
Зарегистрирован: 22.01.2011 20:45:48

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 230

Рейтинг@Mail.ru