Обсуждение статьи "Визуализируй это! Графическая библиотека в MQL5 как аналог plot из R"

 

Опубликована статья Визуализируй это! Графическая библиотека в MQL5 как аналог plot из R:

При исследовании и изучении закономерностей важную роль играет визуальное отображение с помощью графиков. В популярных среди научного сообщества языках программирования, таких как R и Python, для визуализации предназначена специальная функция plot. С её помощью можно рисовать линии, точечные распределения и гистограммы для наглядного представления закономерностей. В MQL5 вы можете делать всё то же самое с помощью класса CGraphics.

Графики на функциях — быстрая генерация в несколько строчек

Еще одно удобство библиотеки — работа с указателями на функции CurveFunction. Указатели на функции в MQL5 принимают только глобальные или статические функции, при этом синтаксис функции должен полностью соответствовать синтаксису указателя. В нашем случае указатель CurveFunction настраивается на функции, которые получают один параметр типа double, и возвращает также double.

Для построения кривой по указателю на функцию нам также потребуется точно задать начальное (from), конечное (to) значение аргумента и его приращение (step). Следовательно, чем меньше значение приращения, тем больше точек функции у нас будет для её построения. Для создания датасерии используйте CurveAdd(), а для отрисовки функции — CurvePlot() или CurvePlotAll().



Ключевые достоинства графической библиотеки

На языке MQL5 разработчики могут не только создавать торговых роботов и технические индикаторы, но также и производить сложные математические расчеты с помощью библиотек ALGLIB, Fuzzy и Статистика. Полученные данные затем легко визуализируются с помощью представленной графической библиотеки. При этом большинство операций автоматизировано, библиотека предлагает обширный функционал:

  • 5 типов отрисовки графика
  • 10 типов маркеров для графика
  • автоматическое масштабирование графиков по осям X и Y
  • автоматический выбор цвета, даже если на график выводится несколько построений
  • сглаживание линий с помощью классического антиальясинга или более продвинутого алгоритма Брезенхема
  • возможность установки параметров сплайн-аппроксимации для вывода линий
  • возможность создавать график одной строчкой кода на основе двух массивов x[] и y[]
  • возможность создания графиков с помощью указателей на функции

Автор: MetaQuotes Software Corp.

 
Хорошая работа проведена! Спасибо. А то уже сам собрался исправлять алгоритм CircleAA
Кстати функцию CircleWu можно упростить и убыстрить:

void CCanvas::CircleWu(const int x,const int y,const double r,const uint clr,const uint style=UINT_MAX)
  {
   if(r<=0)
      return;
//--- preliminary calculations
   double r2=r*r;
   double quarter=round(r*M_SQRT1_2);
//--- set the line style
   uint prev_style=m_style;
   if(style!=UINT_MAX)
      LineStyleSet(style);
   uint mask=1<<m_style_idx;
//--- draw
   for(int dx=0; dx<=quarter; dx++)
     {
      double dy=sqrt(r2-dx*dx);
      double alpha1=dy-floor(dy);
      double alpha2=1-alpha1;
      if((m_style&mask)==mask)
        {
         PixelTransform4(x,y,dx,(int)(dy)+1,clr,alpha1);
         PixelTransform4(x,y,dx,(int)(dy),clr,alpha2);
         PixelTransform4(x,y,(int)dy+1,dx,clr,alpha1);
         PixelTransform4(x,y,(int)dy,dx,clr,alpha2);
        }
      mask<<=1;
      if(mask==0x1000000)
         mask=1;
     }
  
//--- set the previous line style
   if(style!=UINT_MAX)
      m_style=prev_style;
  }
 
Nikolai Semko:
Хорошая работа проведена! Спасибо. А то уже сам собрался исправлять алгоритм CircleAA
Кстати функцию CircleWu можно упростить и убыстрить:
Спасибо за идею, правки будут внесены!
 

Изменять свойства самого графика и каждой из его функций можно в любой момент. К примеру, добавим подписи осей графика, сменим имя кривой и включим для неё режим сплайн-аппроксимации:

#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   CGraphic graphic;
   graphic.Create(0,"Graphic",0,30,30,780,380);
   double x[]={-10,-4,-1,2,3,4,5,6,7,8};
   double y[]={-5,4,-10,23,17,18,-9,13,17,4};
   CCurve *curve=graphic.CurveAdd(x,y,CURVE_LINES);
   curve.Name("Example");                 
   curve.LinesIsSmooth(true);             
   graphic.XAxis().Name("X - axis");      
   graphic.XAxis().NameSize(12);          
   graphic.YAxis().Name("Y - axis");      
   graphic.YAxis().NameSize(12);
   graphic.YAxis().ValuesWidth(15);
   graphic.CurvePlotAll();
   graphic.Update();
   DebugBreak();
  }

 У меня метод называется LinesSmooth LineIsSmooth нету. Продолжаю изучать дальше :)

 

 
Orangetree:

Изменять свойства самого графика и каждой из его функций можно в любой момент. К примеру, добавим подписи осей графика, сменим имя кривой и включим для неё режим сплайн-аппроксимации:

  {
   curve.LinesIsSmooth(true);             

 У меня метод называется LinesSmooth LineIsSmooth нету. Продолжаю изучать дальше :)

 

Метод был переименован позже. Спасибо, поправили в статье
 

А как сделать что бы при перерисовке кривой на графике обновлялась также шкала?

curve5.Update(resultPrices);
    
graphicfirst.Redraw(); и Update()


‌сама кривая обновляется, но шкала со старыми ценами остается и график уезжает за границы холста

нашел, надо сделать CalculateMaxMinValues() :)

 
Maxim Dmitrievsky:
Подскажите как правильно перерисовывать уже созданный график, допустим при изменении значений в массивах. Redraw() и Update() не дают эффекта

Добрый день, как конкретно вы пытались перерисовать график?

Если вам необходимо просто изменить данные для конкретной кривой, то вот рабочий пример:

#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- data 1
   double x1[]={-10,-4,-1,2,3,4,5,6,7,8};
   double y1[]={-5,4,-10,23,17,18,-9,13,17,4};
//--- data 2
   double x2[]={-10,-10,10,10};
   double y2[]={-10,10,-10,10};
//--- graphic
   CGraphic graph;
   graph.HistoryNameWidth(80);
   graph.Create(0,"Graph",0,30,30,830,430);
//--- Points  
   CCurve *curve=graph.CurveAdd(x1,y1,CURVE_LINES);
   graph.CurvePlot(0);
   graph.Update();
   Sleep(1000);
   curve.Update(x2,y2);
   graph.Redraw(true);
   graph.Update();
   Sleep(1000);
  }
P.S. На форуме есть тема относительно библиотеки Graphics, в ней уже поднимался данный вопрос.
 
Roman Konopelko:

Добрый день, как конкретно вы пытались перерисовать график?

Если вам необходимо просто изменить данные для конкретной кривой, то вот рабочий пример:

P.S. На форуме есть тема относительно библиотеки Graphics, в ней уже поднимался данный вопрос.
спасибо, уже разобрался, делал точно так же, только по одному массиву.. нужно просто пересчитать graph.CalculateMaxMinValues() для графика также, тогда шкала обновляется
 
Maxim Dmitrievsky:
спасибо, уже разобрался, делал точно так же, только по одному массиву.. нужно просто пересчитать graph.CalculateMaxMinValues() для графика также, тогда шкала обновляется
Если вы будете вызывать метод CGraphic::Redraw(const bool rescale=false) с параметром true перерасчет шкал будет происходить автоматически(не нужно будет отдельно вызывать CalculateMaxMinValues)
 
Roman Konopelko:
Если вы будете вызывать метод CGraphic::Redraw(const bool rescale=false) с параметром true перерасчет шкал будет происходить автоматически(не нужно будет отдельно вызывать CalculateMaxMinValues)

Точно, понял.. спасибо )
 

Возможно ли сделать две и более шкалы на графике - по аналогии с линейкой, где указаны деления в виде сантиметров и дюймов, при этом указывать значения только, если точка использовалась для построения графика?

Причина обращения: