Discussão do artigo "Visualize isto! Biblioteca gráfica em linguagem MQL5 como equivalente a plot de R"

 

Novo artigo Visualize isto! Biblioteca gráfica em linguagem MQL5 como equivalente a plot de R foi publicado:

A exibição visual usando gráficos desempenha um importante papel na exploração e estudo de padrões regulares. Nas populares linguagens de programação entre a comunidade científica, tais como R e Python, a função especial plot é destinada para visualização. Com ela você pode desenhar linhas, gráficos de dispersão e histogramas para visualizar padrões. Em linguagem MQL5 você pode fazer a mesma coisa usando a classe CGraphics.

Ao utilizar as funções, pode ocorrer o erro "divisão por zero". Você pode resolver este problema de duas maneiras:

  • desativar - no arquivo metaeditor.ini - o controle da divisão por zero
    [Experts]
    FpNoZeroCheckOnDivision=1
  • ou analisar a fórmula a ser utilizada na função e retornar para tais casos um valor válido. Nos arquivos 3Functions.mq5 e bat.mq5 do apêndice, você encontrará um exemplo de tal processamento com ajuda de uma macro.



Autor: MetaQuotes Software Corp.

Visualize isto! Biblioteca gráfica em linguagem MQL5 como equivalente a plot de R
Visualize isto! Biblioteca gráfica em linguagem MQL5 como equivalente a plot de R
  • 2017.03.13
  • MetaQuotes Software Corp.
  • www.mql5.com
A exibição visual usando gráficos desempenha um importante papel na exploração e estudo de padrões regulares. Nas populares linguagens de programação entre a comunidade científica, tais como R e Python, a função especial plot é destinada para visualização. Com ela você pode desenhar linhas, gráficos de dispersão e histogramas para visualizar padrões. Em linguagem MQL5 você pode fazer a mesma coisa usando a classe CGraphics.
 
Bom trabalho! Obrigado. Eu já estava planejando corrigir o algoritmo CircleAA
A propósito, a função CircleWu pode ser simplificada e acelerada:

void CCanvas::CircleWu(const int x,const int y,const double r,const uint clr,const uint style=UINT_MAX)
  {
   if(r<=0)
      return;
//--- cálculos preliminares
   double r2=r*r;
   double quarter=round(r*M_SQRT1_2);
//--- definir o estilo da linha
   uint prev_style=m_style;
   if(style!=UINT_MAX)
      LineStyleSet(style);
   uint mask=1<<m_style_idx;
//--- desenhar
   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;
     }
  
//--- definir o estilo da linha anterior
   if(style!=UINT_MAX)
      m_style=prev_style;
  }
 
Nikolai Semko:
Bom trabalho! Obrigado. Eu já estava planejando corrigir o algoritmo CircleAA
A propósito, a função CircleWu pode ser simplificada e acelerada:
Obrigado pela ideia, as edições serão feitas!
 

Você pode alterar as propriedades do próprio gráfico e de cada uma de suas funções a qualquer momento. Por exemplo, vamos adicionar legendas aos eixos do gráfico, alterar o nome da curva e ativar o modo de aproximação spline para ela:

#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
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:

Você pode alterar as propriedades do próprio gráfico e de cada uma de suas funções a qualquer momento. Por exemplo, vamos adicionar legendas aos eixos do gráfico, alterar o nome da curva e ativar o modo de aproximação spline para ela:

  {
   curve.LinesIsSmooth(true);             

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

 

O método foi renomeado posteriormente. Obrigado, corrigido no artigo
 

Como posso fazer para que, quando uma curva for redesenhada no gráfico, a escala também seja atualizada?

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


a curva em si é atualizada, mas a escala com os preços antigos permanece e o gráfico se move para fora dos limites da tela

Encontrei a solução, preciso fazer CalculateMaxMinValues() :)

 
Maxim Dmitrievsky:
Você poderia me dizer como redesenhar corretamente um gráfico já criado, por exemplo, ao alterar valores em matrizes? Redraw() e Update() não têm efeito

Boa tarde, como exatamente você tentou redesenhar o gráfico?

Se você só precisa alterar os dados de uma curva específica, aqui está um exemplo funcional:

#include <Graphics\Graphic.mqh>
//+------------------------------------------------------------------+
//| Função de início do programa de script|
//+------------------------------------------------------------------+
void OnStart()
  {
//--- dados 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};
//--- dados 2
   double x2[]={-10,-10,10,10};
   double y2[]={-10,10,-10,10};
//--- gráfico
   CGraphic graph;
   graph.HistoryNameWidth(80);
   graph.Create(0,"Graph",0,30,30,830,430);
//--- Pontos
   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. Há um tópico no fórum sobre a biblioteca Graphics, onde essa questão já foi levantada.
 
Roman Konopelko:

Boa tarde, como exatamente você estava tentando redesenhar o gráfico?

Se você só precisa alterar os dados de uma curva específica, aqui está um exemplo funcional:

P.S. Há um tópico no fórum sobre a biblioteca Graphics, no qual essa questão já foi levantada.
Obrigado, já descobri, eu estava fazendo exatamente a mesma coisa, só que em uma matriz... você só precisa recalcular graph.CalculateMaxMinValues() para o gráfico também, então a escala é atualizada.
 
Maxim Dmitrievsky:
Obrigado, já descobri o problema, fiz exatamente a mesma coisa, só que em uma matriz. Você só precisa recalcular graph.CalculateMaxMinValues() para o gráfico também, e então a escala será atualizada.
Se você chamar o método CGraphic::Redraw(const bool rescale=false) com o parâmetro true, as escalas serão recalculadas automaticamente (não há necessidade de chamar CalculateMaxMinValues separadamente).
 
Roman Konopelko:
Se você chamar o método CGraphic::Redraw(const bool rescale=false) com o parâmetro true, as escalas serão recalculadas automaticamente (não há necessidade de chamar CalculateMaxMinValues separadamente).

Certo, entendi. Obrigado)
 

É possível fazer duas ou mais escalas no gráfico - semelhante a uma régua, em que as divisões são dadas em centímetros e polegadas, com valores fornecidos apenas se o ponto foi usado para traçar o gráfico?