Extensión Qt: descripción general de los conceptos básicos del dibujo QCustomPlot

I. Descripción general

Este tutorial utiliza customPlot como puntero a una instancia de QCustomPlot. Si generamos un control en QtCreator, entonces podremos acceder al control correspondiente a través de ui->customPlot (o cualquier nombre que le demos al control).

Podemos crear un nuevo gráfico en el dibujo a través de customPlot->addGraph(). Luego, asigna algunos puntos de datos al gráfico, por ejemplo, a través de customPlot->graph(0)->setData(…), por ejemplo, en forma de dos QVectors que representan xey (clave y valor).

La razón por la que QCustomPlot utiliza los términos clave y valor en lugar de x e y es para permitir una mayor flexibilidad a la hora de asignar qué eje tiene qué función . Entonces, si define el eje izquierdo como el "eje clave" y el eje inferior como el "eje de valores", puede dibujar un gráfico vertical en el lado izquierdo del gráfico.

Por defecto, el control QCustomPlot tiene cuatro ejes: customPlot->xAxis, yAxis, xAxis2 y yAxis2 de tipo QCPAxis, correspondientes a los ejes inferior, izquierdo, superior y derecho respectivamente. Su rango define qué parte del gráfico está visible actualmente: customPlot->xAxis->setRange(- 1,1).

Para realizar cualquier tipo de cambios en el gráfico que se muestra en la pantalla, llame a customPlot->replot() , que equivale a una actualización manual, lo mismo que actualizar() en QPainter. Tenga en cuenta que el nuevo dibujo se produce automáticamente cuando el control cambia de tamaño y activa la interacción integrada del usuario. Por ejemplo, estas interacciones del usuario consisten en arrastrar el rango de ejes con el mouse y hacer zoom con la rueda del mouse.

// 生成数据:
QVector<double> x(101), y(101); // initialize with entries 0..100
for (int i=0; i<101; ++i)
{
    
    
  x[i] = i/50.0 - 1; // x goes from -1 to 1
  y[i] = x[i]*x[i]; // let's plot a quadratic function
}
 
// create graph and assign data to it:
customPlot->addGraph();
customPlot->graph(0)->setData(x, y);

// give the axes some labels:
customPlot->xAxis->setLabel("x");
customPlot->yAxis->setLabel("y");

// set axes ranges, so we see all data:
customPlot->xAxis->setRange(-1, 1);
customPlot->yAxis->setRange(0, 1);
customPlot->replot();

El resultado debería verse como a continuación.

Insertar descripción de la imagen aquí

Los ticks de marcador y los marcadores son seleccionados automáticamente por el eje utilizado actualmente por el eje. Este eje es una instancia del tipo QCPAxisTicker y se puede acceder a él a través de xAxis->ticker(), etc.

Podemos ajustar el número aproximado de ticks que se intentan crear automáticamente a través de xAxis->ticker()->setTickCount(6). La escala de eje predeterminada es ideal para visualizaciones numéricas simples, pero también hay clases especializadas como escala de tiempo, escala de fecha del calendario, escala de categorías, pi (u otras unidades simbólicas) y ejes logarítmicos. Consulte la documentación de QCPAxisTicker para obtener más detalles.

Las etiquetas de los ejes (números) nunca se extenderán más allá de los límites del control, incluso si se vuelven más anchos, porque el control calcula automáticamente los ejes y esto está activado de forma predeterminada. Si las etiquetas de marca y las etiquetas de eje requieren más espacio, se reduce el rectángulo del eje. Si no queremos que los márgenes se determinen automáticamente, deshabilite este comportamiento llamando a customPlot->axisRect()->setAutoMargins(QCP::msNone). También podemos ajustar manualmente los márgenes a través de customPlot->axisRect()->setmargin(…).

2. Cambia la apariencia

1. Tipo de gráfico

La apariencia de un gráfico está determinada por muchos factores, todos los cuales pueden modificarse. Aquí están los puntos más importantes:

  • Estilo de línea : llamar gráfico->setLineStyle(…). Para conocer todos los estilos de línea posibles, consulte la documentación de QCPGraph::LineStyle o las capturas de pantalla de demostración de estilos de línea en la página introductoria.
    Insertar descripción de la imagen aquí
tipo de enumerador significado
lsNinguno Los puntos de datos no están conectados a ninguna línea recta (por ejemplo, los datos están representados sólo por símbolos según el patrón de dispersión)
lsLínea Los puntos de datos están conectados por una línea recta.
lsPasoIzquierda La línea se dibuja como un paso, donde la altura del paso es el valor del punto de datos de la izquierda.
lsPasoDerecha Las líneas se dibujan como escalones, donde la altura del escalón es el valor del punto de datos correcto
lsStepCenter Cuando el tamaño del paso se encuentra entre dos puntos de datos, la línea se dibuja como el tamaño del paso.
lsImpulso Cada punto de datos está representado por una línea paralela al eje de valores, que se extiende desde el punto de datos hasta la línea de valor cero.
  • Lápiz de línea : todos los lápices proporcionados por el marco QPainter están disponibles, como línea continua, línea discontinua, línea de puntos, diferentes anchos, colores, transparencia, etc. El pincel configurado se configura a través de gráfico->setPen(...).
  • Símbolos de dispersión : llame a gráfico->setScatterStyle(…) para cambiar la apariencia de los símbolos de dispersión. Para conocer todos los estilos de dispersión posibles, consulte la documentación de QCPScatterStyle o la captura de pantalla de demostración de estilo de dispersión que se muestra en la página introductoria. Si no queremos que se muestre ningún símbolo de dispersión en los puntos de datos, establezca el estilo de dispersión del gráfico en QCPScatterStyle::ssNone.
tipo de enumeración Exterior significado
ssNinguno Los símbolos de dispersión no se trazan (por ejemplo, en QCPGraph los datos se representan solo mediante líneas)
sspunto Un solo píxel (si desea un círculo con un radio determinado, puede usar ssDisc o scircle)
ssCruz Insertar descripción de la imagen aquí al otro lado de
ssPlus Insertar descripción de la imagen aquí un+
ssCírculo ssCírculo.png un circulo
ssDisco ssDisc.png Un círculo lleno del color de un bolígrafo (no lleno de un pincel como un círculo)
ssCuadrado ssCuadrado.png un cuadrado
ssDiamante ssDiamond.png un diamante
ssEstrella ssEstrella.png Una estrella con ocho brazos, una combinación de cruz y signo más.
ssTriángulo ssTriángulo.png Triángulo equilátero sobre la línea de base.
ssTriánguloInvertido ssTriangleInverted.png Un triángulo equilátero que se encuentra en las esquinas.
ssCruzCuadrado ssCrossSquare.png cuadrado con una cruz
ssPlusCuadrado ssPlusSquare.png Un cuadrado con un signo más en su interior.
ssCruzCírculo ssCrossCircle.png un círculo con una cruz dentro
ssPlusCírculo ssPlusCircle.png Un círculo con un signo más dentro.
ssPaz ssPeace.png Un círculo con una línea vertical y dos diagonales hacia abajo.
ssPixmap Mapa de píxeles personalizado especificado por setPixmap, centrado en las coordenadas del punto de datos
ssPersonalizado Realice una operación de dibujo personalizada por dispersión (como QPainterPath, consulte setCustomPath)
  • Relleno debajo de Gráfico o entre dos Gráficos : todos los pinceles proporcionados por el marco QPainter se pueden usar para rellenar Gráficos: entidades, varios patrones, texturas, degradados, colores, transparencia, etc. Configure el pincel configurado a través de gráfico->setBrush(...).

2. Eje de coordenadas del eje.

Podemos modificar la apariencia de los ejes cambiando el lápiz utilizado para dibujar los ejes y la fuente utilizada para las etiquetas. Debería explicarse por sí solo consultando la documentación de QCPAxis. Aquí hay un resumen rápido de las propiedades más importantes:

  • establecerBasePen,
  • establecer tickpen,
  • establecer longitud de garrapata,
  • establecerSubTickLength,
  • establecerSubTickPen,
  • establecerTickLabelFont,
  • establecer fuente de etiqueta,
  • setTickLabelPadding,
  • setLabelPadding。

Puede invertir un eje (por ejemplo, hacer que los valores disminuyan de izquierda a derecha en lugar de aumentar) con setRangeReversed.

Si desea una decoración en el extremo del eje (como una flecha), use setLowerEnding o setUpperEnding.

3. Cuadrícula

Podemos modificar la grilla accediendo a la instancia QCPGrid correspondiente del eje.

Por ejemplo, cambie la apariencia de las líneas de la cuadrícula horizontal vinculadas al eje izquierdo accediendo a customPlot->yAxis->grid(). La apariencia de las líneas de la cuadrícula es básicamente el QPen en el que están dibujadas, que se puede configurar mediante yAxis->grid()->setPen(). La línea de la cuadrícula en el punto 0 se puede dibujar con un lápiz diferente o se puede configurar con setZeroLinePen. Si no queremos que la línea cero se dibuje con un lápiz especial, simplemente configúrelo en Qt::NoPen y la línea de la cuadrícula en la marca 0 se dibujará con un lápiz de cuadrícula normal.
Las líneas secundarias están configuradas como invisibles de forma predeterminada. Se pueden activar mediante grid()->setSubGridVisible(true).

3. Caso

1. Diseño simple de dos imágenes.

A continuación se muestra un ejemplo que crea una gráfica de la función coseno desintegrada y su envolvente exponencial:

Insertar descripción de la imagen aquí

// 添加两个图并设置外观:
customPlot->addGraph();
customPlot->graph(0)->setPen(QPen(Qt::blue)); // 第一张图的线条颜色为蓝色
customPlot->graph(0)->setBrush(QBrush(QColor(0, 0, 255, 20))); //第一个Graph将被半透明的蓝色填充
customPlot->addGraph();
customPlot->graph(1)->setPen(QPen(Qt::red)); // 第二张图的线条颜色为红色

// 生成一些数据点(第一张图为y0,第二张图为y1):
QVector<double> x(251), y0(251), y1(251);
for (int i=0; i<251; ++i)
{
    
    
  x[i] = i;
  y0[i] = qExp(-i/150.0)*qCos(i/10.0); // 指数衰减余弦
  y1[i] = qExp(-i/150.0);              // 指数函数
}

// configure right and top axis to show ticks but no labels:
// (see QCPAxisRect::setupFullAxesBox for a quicker method to do this)
customPlot->xAxis2->setVisible(true);
customPlot->xAxis2->setTickLabels(false);
customPlot->yAxis2->setVisible(true);
customPlot->yAxis2->setTickLabels(false);

// make left and bottom axes always transfer their ranges to right and top axes:
connect(customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->xAxis2, SLOT(setRange(QCPRange)));
connect(customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), customPlot->yAxis2, SLOT(setRange(QCPRange)));

// pass data points to graphs:
customPlot->graph(0)->setData(x, y0);
customPlot->graph(1)->setData(x, y1);

// let the ranges scale themselves so graph 0 fits perfectly in the visible area:
customPlot->graph(0)->rescaleAxes();

// same thing for graph 1, but only enlarge ranges (in case graph 1 is smaller than graph 0):
customPlot->graph(1)->rescaleAxes(true);

// Note: we could have also just called customPlot->rescaleAxes(); instead
// Allow user to drag axis ranges with mouse, zoom with mouse wheel and select graphs by clicking:
customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);

Como puedes ver, aplicar un relleno a un Gráfico es tan simple como configurar un pincel que no sea Qt::NoBrush. El relleno será desde el Gráfico (aquí Gráfico0) hasta la línea de valor cero paralela al eje clave (aquí x). Si queremos llenar un canal entre este gráfico y otro gráfico, además llamaremos gráfico->setChannelFillGraph(otherGraph). Para eliminar el relleno del canal, simplemente pase 0 como otherGraph y el relleno llegará hasta la línea de valor cero como antes. Para eliminar el relleno por completo, llame a graph->setBrush(Qt::NoBrush).

2. Trazar con múltiples ejes y estilos más avanzados

Ahora, veamos un ejemplo más complejo, creando una captura de pantalla de demostración con cinco gráficos en cuatro ejes, rellenos de textura, barras de error verticales, leyenda, puntos como separadores decimales, etc.

112

customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom)); // period as decimal separator and comma as thousand separator
customPlot->legend->setVisible(true);
QFont legendFont = font();  // start out with MainWindow's font..
legendFont.setPointSize(9); // and make a bit smaller for legend
customPlot->legend->setFont(legendFont);
customPlot->legend->setBrush(QBrush(QColor(255,255,255,230)));
// by default, the legend is in the inset layout of the main axis rect. So this is how we access it to change legend placement:
customPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignBottom|Qt::AlignRight);
 
// setup for graph 0: key axis left, value axis bottom
// will contain left maxwell-like function
customPlot->addGraph(customPlot->yAxis, customPlot->xAxis);
customPlot->graph(0)->setPen(QPen(QColor(255, 100, 0)));
customPlot->graph(0)->setBrush(QBrush(QPixmap("./balboa.jpg"))); // fill with texture of specified image
customPlot->graph(0)->setLineStyle(QCPGraph::lsLine);
customPlot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 5));
customPlot->graph(0)->setName("Left maxwell function");
 
// setup for graph 1: key axis bottom, value axis left (those are the default axes)
// will contain bottom maxwell-like function with error bars
customPlot->addGraph();
customPlot->graph(1)->setPen(QPen(Qt::red));
customPlot->graph(1)->setBrush(QBrush(QPixmap("./balboa.jpg"))); // same fill as we used for graph 0
customPlot->graph(1)->setLineStyle(QCPGraph::lsStepCenter);
customPlot->graph(1)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, Qt::red, Qt::white, 7));
customPlot->graph(1)->setName("Bottom maxwell function");
QCPErrorBars *errorBars = new QCPErrorBars(customPlot->xAxis, customPlot->yAxis);
errorBars->removeFromLegend();
errorBars->setDataPlottable(customPlot->graph(1));
 
// setup for graph 2: key axis top, value axis right
// will contain high frequency sine with low frequency beating:
customPlot->addGraph(customPlot->xAxis2, customPlot->yAxis2);
customPlot->graph(2)->setPen(QPen(Qt::blue));
customPlot->graph(2)->setName("High frequency sine");
 
// setup for graph 3: same axes as graph 2
// will contain low frequency beating envelope of graph 2
customPlot->addGraph(customPlot->xAxis2, customPlot->yAxis2);
QPen blueDotPen;
blueDotPen.setColor(QColor(30, 40, 255, 150));
blueDotPen.setStyle(Qt::DotLine);
blueDotPen.setWidthF(4);
customPlot->graph(3)->setPen(blueDotPen);
customPlot->graph(3)->setName("Sine envelope");
 
// setup for graph 4: key axis right, value axis top
// will contain parabolically distributed data points with some random perturbance
customPlot->addGraph(customPlot->yAxis2, customPlot->xAxis2);
customPlot->graph(4)->setPen(QColor(50, 50, 50, 255));
customPlot->graph(4)->setLineStyle(QCPGraph::lsNone);
customPlot->graph(4)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 4));
customPlot->graph(4)->setName("Some random data around\na quadratic function");
 
// generate data, just playing with numbers, not much to learn here:
QVector<double> x0(25), y0(25);
QVector<double> x1(15), y1(15), y1err(15);
QVector<double> x2(250), y2(250);
QVector<double> x3(250), y3(250);
QVector<double> x4(250), y4(250);
for (int i=0; i<25; ++i) // data for graph 0
{
    
    
  x0[i] = 3*i/25.0;
  y0[i] = qExp(-x0[i]*x0[i]*0.8)*(x0[i]*x0[i]+x0[i]);
}
for (int i=0; i<15; ++i) // data for graph 1
{
    
    
  x1[i] = 3*i/15.0;;
  y1[i] = qExp(-x1[i]*x1[i])*(x1[i]*x1[i])*2.6;
  y1err[i] = y1[i]*0.25;
}
for (int i=0; i<250; ++i) // data for graphs 2, 3 and 4
{
    
    
  x2[i] = i/250.0*3*M_PI;
  x3[i] = x2[i];
  x4[i] = i/250.0*100-50;
  y2[i] = qSin(x2[i]*12)*qCos(x2[i])*10;
  y3[i] = qCos(x3[i])*10;
  y4[i] = 0.01*x4[i]*x4[i] + 1.5*(rand()/(double)RAND_MAX-0.5) + 1.5*M_PI;
}
 
// pass data points to graphs:
customPlot->graph(0)->setData(x0, y0);
customPlot->graph(1)->setData(x1, y1);
errorBars->setData(y1err);
customPlot->graph(2)->setData(x2, y2);
customPlot->graph(3)->setData(x3, y3);
customPlot->graph(4)->setData(x4, y4);
// activate top and right axes, which are invisible by default:
customPlot->xAxis2->setVisible(true);
customPlot->yAxis2->setVisible(true);
// set ranges appropriate to show data:
customPlot->xAxis->setRange(0, 2.7);
customPlot->yAxis->setRange(0, 2.6);
customPlot->xAxis2->setRange(0, 3.0*M_PI);
customPlot->yAxis2->setRange(-70, 35);
// set pi ticks on top axis:
customPlot->xAxis2->setTicker(QSharedPointer<QCPAxisTickerPi>(new QCPAxisTickerPi));
// add title layout element:
customPlot->plotLayout()->insertRow(0);
customPlot->plotLayout()->addElement(0, 0, new QCPTextElement(customPlot, "Way too many graphs in one plot", QFont("sans", 12, QFont::Bold)));
// set labels:
customPlot->xAxis->setLabel("Bottom axis with outward ticks");
customPlot->yAxis->setLabel("Left axis label");
customPlot->xAxis2->setLabel("Top axis label");
customPlot->yAxis2->setLabel("Right axis label");
// make ticks on bottom axis go outward:
customPlot->xAxis->setTickLength(0, 5);
customPlot->xAxis->setSubTickLength(0, 3);
// make ticks on right axis go inward and outward:
customPlot->yAxis2->setTickLength(3, 3);
customPlot->yAxis2->setSubTickLength(1, 1);

Como podemos ver, somos libres de definir qué eje debe desempeñar qué papel en el Gráfico. Por ejemplo, un gráfico con índice 0 utiliza el eje izquierdo (yAxis) como clave y el eje inferior (xAxis) como valor. Por lo tanto, el gráfico está hacia arriba con respecto al eje izquierdo:

Para mostrar las barras de error de Graph1, creamos una instancia de QCPErrorBars que se puede adjuntar a otras tablas de trazado (como QCPGraph) y les proporcionamos barras de error. Para obtener más explicaciones de los métodos utilizados, consulte la documentación correspondiente.

3. Trazar datos de fecha y hora

A continuación, veremos cómo trazar datos relacionados con la fecha y/o la hora. Básicamente se reduce a instalar diferentes ticks de eje del tipo QCPAxisTickerDateTime en sus respectivos ejes.

Insertar descripción de la imagen aquí

// set locale to english, so we get english month names:
customPlot->setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));

// seconds of current time, we'll use it as starting point in time for data:
double now = QDateTime::currentDateTime().toTime_t();
srand(8); // set the random seed, so we always get the same random data

// create multiple graphs:
for (int gi=0; gi<5; ++gi)
{
    
    
  customPlot->addGraph();
  QColor color(20+200/4.0*gi,70*(1.6-gi/4.0), 150, 150);
  customPlot->graph()->setLineStyle(QCPGraph::lsLine);
  customPlot->graph()->setPen(QPen(color.lighter(200)));
  customPlot->graph()->setBrush(QBrush(color));
  
  // generate random walk data:
  QVector<QCPGraphData> timeData(250);
  for (int i=0; i<250; ++i)
  {
    
    
    timeData[i].key = now + 24*3600*i;
    if (i == 0)
      timeData[i].value = (i/50.0+1)*(rand()/(double)RAND_MAX-0.5);
    else
      timeData[i].value = qFabs(timeData[i-1].value)*(1+0.02/4.0*(4-gi)) + (i/50.0+1)*(rand()/(double)RAND_MAX-0.5);
  }
  customPlot->graph()->data()->set(timeData);
}

// configure bottom axis to show date instead of number:
QSharedPointer<QCPAxisTickerDateTime> dateTicker(new QCPAxisTickerDateTime);
dateTicker->setDateTimeFormat("d. MMMM\nyyyy");
customPlot->xAxis->setTicker(dateTicker);

// configure left axis text labels:
QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
textTicker->addTick(10, "a bit\nlow");
textTicker->addTick(50, "quite\nhigh");
customPlot->yAxis->setTicker(textTicker);

// set a more compact font size for bottom and left axis tick labels:
customPlot->xAxis->setTickLabelFont(QFont(QFont().family(), 8));
customPlot->yAxis->setTickLabelFont(QFont(QFont().family(), 8));

// set axis labels:
customPlot->xAxis->setLabel("Date");
customPlot->yAxis->setLabel("Random wobbly lines value");

// make top and right axes visible but without ticks and labels:
customPlot->xAxis2->setVisible(true);
customPlot->yAxis2->setVisible(true);
customPlot->xAxis2->setTicks(false);
customPlot->yAxis2->setTicks(false);
customPlot->xAxis2->setTickLabels(false);
customPlot->yAxis2->setTickLabels(false);

// set axis ranges to show all data:
customPlot->xAxis->setRange(now, now+24*3600*249);
customPlot->yAxis->setRange(0, 60);

// show legend with slightly transparent background brush:
customPlot->legend->setVisible(true);
customPlot->legend->setBrush(QColor(255, 255, 255, 150));

La cadena pasada a dateTicker->setDateTimeFormat() tiene las mismas opciones de formato de fecha que la cadena pasada a QDateTime::toString, consulte la documentación de Qt. Todas las coordenadas de fecha/hora en QCustomPlot se tratan como segundos desde la medianoche 1. Enero de 1970, UTC (conocido como Unix/Epoch Time). Esta es también la unidad que usamos cuando llamamos a QDateTime::toTime_t o setTime_t en las clases de fecha/hora de Qt.

Para una precisión inferior a un segundo, los temporizadores de eje funcionan con números de coma flotante. Por tanto, los valores inferiores a 1,0 representan la fracción de segundo correspondiente. Podemos usar QCPAxisTickerDateTime::dateTimeToKey y keyToDateTime para convertir la hora Unix de punto flotante y QDateTime, independientemente de la versión de Qt (QDateTime::toMSecsSinceEpoch de Qt solo se introdujo en Qt 4.7).

4. Otros Gráficos: curvas, gráficos de barras, diagramas estadísticos,…

Hasta ahora sólo hemos mirado los gráficos. Dado que son un caso de uso principal, QCustomPlot proporciona una interfaz dedicada para ellos. Lo usamos todo el tiempo: QCustomPlot::addGraph, QCustomPlot::graph, etc. Pero esa no es toda la historia. QCustomPlot tiene una interfaz más general para las clases utilizadas para trazar datos en gráficos, llamada Plottables.

Esta interfaz se basa en la clase base abstracta QCPAbstractPlottable. Todos los Plottables provienen de esta clase, así como de la familiar clase QCPGraph. QCustomPlot proporciona muchas otras clases de trazado:

  • QCPGraph : esta es la clase gráfica que hemos estado usando. Muestra una serie de puntos de datos como un gráfico con diferentes estilos de línea, rellenos y puntos de dispersión.

  • QCPCurve : Similar a QCPGraph, excepto que se usa para mostrar curvas paramétricas. A diferencia de las gráficas de funciones, pueden tener ciclos.

  • QCPBars : un gráfico de barras. Tome una serie de puntos de datos y represéntelos como barras. Si tiene varios gráficos qcpbar en su gráfico, puede apilarlos como se muestra en la captura de pantalla de la página introductoria.

  • QCPStatisticalBox : diagrama de caja estadístico. Tome un resumen de cinco dígitos (mínimo, cuartil inferior, mediana, cuartil superior, máximo) y representelo como un cuadro de estadísticas. También se pueden mostrar valores atípicos.

  • QCPColorMap : un mapa 2D que visualiza la tercera dimensión de los datos mediante el uso de degradados de color. La clase QCPColorScale acompaña a este gráfico para visualizar la escala de datos en el gráfico.

  • QCPFinancial : un gráfico que puede utilizar velas japonesas o barras OHLC para visualizar, por ejemplo, información de apertura, máximo, mínimo y cierre del precio de las acciones.

  • QCPErrorBars : este es un gráfico especial porque está adjunto a un segundo gráfico para permitir que se muestren barras de error en los puntos de datos del otro gráfico.

A diferencia de QCPGraph, es necesario crear otros gráficos utilizando un nuevo QCustomPlot externo . Esto significa que no existe la función addCurve o addBars, pero sí la función addGraph.

La instancia de QCustomPlot a la que pertenece el trazado se infiere de los ejes pasados ​​en el constructor del trazado. QCustomPlot luego toma posesión del trazado. Se puede acceder a las tablas de trazado existentes usando QCustomPlot::plottable(int index), y el número total de tablas de trazado en un gráfico (incluido Graph) se puede recuperar usando QCustomPlot::plottableCount . Por supuesto, podemos configurar un mapa nosotros mismos para mantener esta relación de índice.

A continuación se muestra un ejemplo rápido de cómo crear tres histogramas:

QCPBars *myBars = new QCPBars(customPlot->xAxis, customPlot->yAxis);
// now we can modify properties of myBars:
myBars->setName("Bars Series 1");
QVector<double> keyData;
QVector<double> valueData;
keyData << 1 << 2 << 3;
valueData << 2 << 4 << 8;
myBars->setData(keyData, valueData);
customPlot->rescaleAxes();
customPlot->replot();

Se pueden encontrar más detalles sobre otros dibujos en los proyectos de muestra y otros tutoriales. Además, cada tipo de diseño se describe en detalle en la página de documentación de la clase respectiva.

Por supuesto, es completamente posible escribir nuestros propios gráficos para que los datos se vean exactamente como los necesitamos. Deberíamos consultar la documentación de QCPAbstractPlottable para saber cómo comenzar a crear subclases. También podemos mirar las parcelas existentes para ver cómo funcionan.

Para ello, se recomienda mirar primero QCPBars o QCPCurve. QCPGraph tiene muchas funciones , por lo que puede no ser un punto de partida adecuado.

Supongo que te gusta

Origin blog.csdn.net/qq_43680827/article/details/133444525
Recomendado
Clasificación