Vespucci  1.0.0
mapplot.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright (C) 2014-2016 Wright State University - All Rights Reserved
3  Daniel P. Foose - Maintainer/Lead Developer
4 
5  This file is part of Vespucci.
6 
7  Vespucci is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  Vespucci is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with Vespucci. If not, see <http://www.gnu.org/licenses/>.
19 *******************************************************************************/
20 #include "mapplot.h"
21 
22 MapPlot::MapPlot(QWidget *parent)
23  : QCustomPlot(parent)
24 {
25  vertical_crosshair_ = new QCPItemStraightLine(this);
26  horizontal_crosshair_ = new QCPItemStraightLine(this);
27  QPen crosshair_pen(Qt::red);
28  crosshair_pen.setWidth(3);
29  vertical_crosshair_->setPen(crosshair_pen);
30  horizontal_crosshair_->setPen(crosshair_pen);
31 
32 
33  addItem(vertical_crosshair_);
34  addItem(horizontal_crosshair_);
35 
36  color_map_= new QCPColorMap(xAxis, yAxis);
37  color_scale_ = new QCPColorScale(this);
38  color_map_->setColorScale(color_scale_);
39 
40  color_map_->setInterpolate(false);
41  addLayer("crosshairs");
42  vertical_crosshair_->setLayer("crosshairs");
43  horizontal_crosshair_->setLayer("crosshairs");
44 
45  addPlottable(color_map_);
46 
47  QCPAxisRect *rect = axisRect();
48  plotLayout()->addElement(0, 1, rect);
49  plotLayout()->remove(plotLayout()->element(0, 0));
50  plotLayout()->addElement(0, 0, color_scale_);
51  rect_position_ = QPair<int, int>(0, 1);
52  color_scale_position_ = QPair<int, int>(0, 0);
53 
54 
55  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
56  color_scale_->setType(QCPAxis::atLeft);
57  addLayer("colorscale");
58  color_scale_->setLayer("colorscale");
59  QCPMarginGroup *group = new QCPMarginGroup(this);
60  color_scale_->setMarginGroup(QCP::msTop|QCP::msBottom, group);
62  color_scale_->setLabel(" ");
63  xAxis->setVisible(false);
64  yAxis->setVisible(false);
65 
66  color_map_->setTightBoundary(false);
67 
69 }
70 
77 void MapPlot::SetMapData(const vec &x, const vec &y, const vec &z)
78 {
79  if ((x.n_elem != y.n_elem) || (x.n_elem != z.n_elem) || (y.n_elem != z.n_elem))
80  throw std::invalid_argument("Vector sizes do not match!");
81  y_ = y;
82  x_ = x;
83  z_ = z;
84  vec unique_x = sort(unique(x_));
85  vec unique_y = sort(unique(y_));
86  uword x_size = unique_x.n_rows;
87  uword y_size = unique_y.n_rows;
88  x_step_ = unique_x(1) - unique_x(0);
89  y_step_ = unique_y(1) - unique_y(0);
90 
91  QCPRange x_range(x_.min(), x_.max());
92  QCPRange y_range(y_.min(), y_.max());
93 
94  color_map_->data()->setKeySize(x_size);
95  color_map_->data()->setValueSize(y_size);
96  color_map_->data()->setKeyRange(x_range);
97  color_map_->data()->setValueRange(y_range);
98  for (uword i = 0; i < x.n_elem; ++i){
99  color_map_->data()->setData(x_(i), y_(i), z_(i));
100  }
101  rescaleAxes();
103 
104  QCPRange x_axis_range(x_range.lower - (x_step_ / 2.0), x_range.upper + (x_step_ / 2.0));
105  QCPRange y_axis_range(y_range.lower - (y_step_ / 2.0), y_range.upper + (y_step_ / 2.0));
106 
107  xAxis->setRange(x_axis_range);
108  yAxis->setRange(y_axis_range);
110 }
111 
113 {
114  color_scale_ = scale;
115  color_map_->setColorScale(scale);
117 }
118 
120 {
121  color_map_->setGradient(gradient);
122  color_map_->rescaleDataRange(true);
124 }
125 
127 {
128  color_scale_->setDataRange(gradient.range);
129  color_scale_->setGradient(gradient.gradient);
130  color_map_->setGradient(gradient.gradient);
131 }
132 
137 {
138  double x_min = x_.min();
139  double x_max = x_.max();
140  double y_min = y_.min();
141  double y_max = y_.max();
142  double x_center = (x_min + x_max) / 2.0;
143  double y_center = (y_min + y_max) / 2.0;
144 
145  vec xdif = arma::abs(x_ - x_center);
146  vec ydif = arma::abs(y_ - y_center);
147  x_center = x_(xdif.index_min());
148  y_center = y_(ydif.index_min());
149 
150  horizontal_crosshair_->point1->setCoords(x_min, y_center);
151  horizontal_crosshair_->point2->setCoords(x_max, y_center);
152  vertical_crosshair_->point1->setCoords(x_center, y_min);
153  vertical_crosshair_->point2->setCoords(x_center, y_max);
154 
155  horizontal_crosshair_->setVisible(true);
156  vertical_crosshair_->setVisible(true);
157 
158 }
159 
167 uword MapPlot::GetCrosshairPosition(double &x, double &y, double &z)
168 {
169  uword index = GetCrosshairPosition();
170  x = x_(index);
171  y = y_(index);
172  z = z_(index);
173  return index;
174 }
175 
177 {
178  double x_pos = vertical_crosshair_->point1->coords().x();
179  double y_pos = horizontal_crosshair_->point1->coords().y();
180 
181  if (x_pos > x_.max()) x_pos = x_.max();
182  if (x_pos < x_.min()) x_pos = x_.min();
183  if (y_pos > y_.max()) y_pos = y_.max();
184  if (y_pos < y_.min()) y_pos = y_.min();
185 
186  vec xy = arma::abs(x_ - x_pos) + arma::abs(y_ - y_pos);
187  uword index = xy.index_min();
188  emit CoordinatesChanged(x_(index), y_(index), z_(index));
189  return index;
190 }
191 
192 double MapPlot::min() const
193 {
194  return z_.min();
195 }
196 
197 double MapPlot::max() const
198 {
199  return z_.max();
200 }
201 
207 {
208  QPointF point1_pos = vertical_crosshair_->point1->coords();
209  QPointF point2_pos = vertical_crosshair_->point2->coords();
210 
211  double new_x = point1_pos.x() + double(units)*x_step_;
212  new_x = (new_x > x_.max() ? x_.max() : new_x);
213  new_x = (new_x < x_.min() ? x_.min() : new_x);
214 
215  point1_pos.setX(new_x);
216  point2_pos.setX(new_x);
217 
218  vertical_crosshair_->point1->setCoords(point1_pos);
219  vertical_crosshair_->point2->setCoords(point2_pos);
222 }
223 
229 {
230  QPointF point1_pos = horizontal_crosshair_->point1->coords();
231  QPointF point2_pos = horizontal_crosshair_->point2->coords();
232  double new_y = point1_pos.y() + double(units)*y_step_;
233  new_y = (new_y > y_.max() ? y_.max() : new_y);
234  new_y = (new_y < y_.min() ? y_.min() : new_y);
235 
236  point1_pos.setY(new_y);
237  point2_pos.setY(new_y);
238 
239  horizontal_crosshair_->point1->setCoords(point1_pos);
240  horizontal_crosshair_->point2->setCoords(point2_pos);
241 
244 }
245 
246 void MapPlot::SaveImage(QString filename)
247 {
248  layer("crosshairs")->setVisible(false);
249  Vespucci::SavePlot(this, filename);
250  layer("crosshairs")->setVisible(true);
252 }
253 
255 {
256  double extremum = std::max(std::abs(color_map_->dataRange().upper),
257  std::abs(color_map_->dataRange().lower));
258  color_map_->setDataRange(QCPRange(-1.0*extremum, extremum));
259  color_scale_->setDataRange(QCPRange(-1.0*extremum, extremum));
261 }
262 
263 void MapPlot::rescaleDataRange(bool onlyVisibleMaps)
264 {
265  color_scale_->rescaleDataRange(onlyVisibleMaps);
266 }
267 
268 void MapPlot::setDataRange(const QCPRange &dataRange)
269 {
270  color_scale_->setDataRange(dataRange);
271  replot();
272  repaint();
273 }
274 
275 void MapPlot::ColorScaleVisible(bool visible)
276 {
277  color_scale_->setVisible(visible);
278 }
279 
280 void MapPlot::CrossHairsVisible(bool visible)
281 {
282  vertical_crosshair_->setVisible(visible);
283  horizontal_crosshair_->setVisible(visible);
284 }
285 
286 void MapPlot::SetFonts(const QFont &font)
287 {
288  setFont(font);
289 
290  xAxis->setLabelFont(font);
291  xAxis->setTickLabelFont(font);
292 
293  xAxis2->setLabelFont(font);
294  xAxis2->setTickLabelFont(font);
295 
296  yAxis->setLabelFont(font);
297  yAxis->setTickLabelFont(font);
298 
299  yAxis2->setLabelFont(font);
300  yAxis2->setTickLabelFont(font);
301 
302  legend->setFont(font);
303 
304  color_scale_->axis()->setLabelFont(font);
305  color_scale_->axis()->setTickLabelFont(font);
306 }
307 
308 void MapPlot::SetColorScaleLabel(const QString &label_text)
309 {
310  color_scale_->setLabel(label_text);
312 }
313 
315 {
316  return color_scale_->label();
317 }
318 
320 {
321  color_scale_->axis()->setAutoTickCount(ticks);
322 }
323 
324 void MapPlot::SetColorScaleTicks(double min, double max, size_t count)
325 {
326  color_scale_->axis()->setAutoTicks(false);
327  vec ticks = linspace(min, max, count);
328  qvec tick_qv = qvec::fromStdVector(conv_to<stdvec>::from(ticks));
329  color_scale_->axis()->setAutoTickLabels(true);
330  color_scale_->axis()->setTickVector(tick_qv);
332 }
333 
334 void MapPlot::SetClusterTicks(size_t count)
335 {
336  QVector<QString> tick_labels;
337  QVector<double> tick_vector;
338  double tick_step = (z_.max() - z_.min())/count;
339  color_scale_->axis()->setAutoTicks(false);
340  color_scale_->axis()->setAutoTickLabels(false);
341  color_scale_->axis()->setAutoTickStep(false);
342  color_scale_->axis()->setAutoSubTicks(false);
343  color_scale_->axis()->setSubTickCount(0);
344  for (size_t i = 0; i < count; ++i){
345  tick_vector.push_back(z_.min() + (tick_step / 2.0) + (double(i) * tick_step));
346  tick_labels.push_back(QString::number(i+1));
347  }
348  color_scale_->axis()->setTickVector(tick_vector);
349  color_scale_->axis()->setTickVectorLabels(tick_labels);
351 }
352 
354 {
355  color_map_->setInterpolate(interpolate);
356 }
357 
359 {
360  return color_map_->interpolate();
361 }
362 
364 {
365  return color_map_->data()->keySize();
366 }
367 
369 {
370  return color_map_->data()->valueSize();
371 }
372 
374 {
375  return color_map_->keyAxis()->range();
376 }
377 
379 {
380  return color_map_->valueAxis()->range();
381 }
382 
383 void MapPlot::ShowCrosshairs(bool show)
384 {
385  vertical_crosshair_->setVisible(show);
386  horizontal_crosshair_->setVisible(show);
387 }
QCPLayoutGrid * plotLayout() const
Definition: qcustomplot.h:1728
A margin group allows synchronization of margin sides if working with multiple layout elements...
Definition: qcustomplot.h:605
void SetGradient(QCPColorGradient gradient)
Definition: mapplot.cpp:119
QString ColorScaleLabel() const
Definition: mapplot.cpp:314
void ColorScaleVisible(bool visible)
Definition: mapplot.cpp:275
0x08 bottom margin
Definition: qcustomplot.h:108
void setAutoTickLabels(bool on)
void setKeySize(int keySize)
void CenterAtZero()
Definition: mapplot.cpp:254
void setType(QCPAxis::AxisType type)
Q_SLOT bool setLayer(QCPLayer *layer)
void setVisible(bool visible)
bool remove(QCPLayoutElement *element)
Q_SLOT void setDataRange(const QCPRange &dataRange)
const QCPRange range() const
Definition: qcustomplot.h:1101
0x04 top margin
Definition: qcustomplot.h:107
QCPColorMapData * data() const
Definition: qcustomplot.h:3112
void SetMapData(const vec &x, const vec &y, const vec &z)
MapPlot::SetMapData.
Definition: mapplot.cpp:77
void SetFonts(const QFont &font)
Definition: mapplot.cpp:286
void setAutoTickStep(bool on)
double min() const
Definition: mapplot.cpp:192
void setSubTickCount(int count)
void setAutoTicks(bool on)
void rescaleDataRange(bool onlyVisibleMaps)
QCPColorGradient gradient
Definition: global.h:30
void setAutoSubTicks(bool on)
VESPUCCI_EXPORT arma::uword max(arma::uword a, arma::uword b)
Vespucci::Math::max.
Definition: accessory.cpp:237
void setInterpolate(bool interpolate)
Definition: mapplot.cpp:353
QCPAxis * xAxis
Definition: qcustomplot.h:1824
bool interpolate() const
Definition: mapplot.cpp:358
void setCoords(double key, double value)
void CrossHairsVisible(bool visible)
Definition: mapplot.cpp:280
int valueSize() const
Definition: qcustomplot.h:3057
bool addElement(int row, int column, QCPLayoutElement *element)
void setValueSize(int valueSize)
bool interpolate() const
Definition: qcustomplot.h:3115
void MoveHorizontalCrosshair(int units)
MapPlot::MoveHorizontalCrosshair.
Definition: mapplot.cpp:228
void setColorScale(QCPColorScale *colorScale)
QPointF coords() const
Definition: qcustomplot.h:1576
void setAutoTickCount(int approximateCount)
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpHint)
void SetColorScale(QCPColorScale *scale)
Definition: mapplot.cpp:112
void setTickLabelFont(const QFont &font)
void setData(double key, double value, double z)
Q_SLOT void setGradient(const QCPColorGradient &gradient)
void ShowCrosshairs(bool show)
Definition: mapplot.cpp:383
void CenterCrosshairs()
MapPlot::CenterCrosshairs Positions the crosshairs in the center of the map.
Definition: mapplot.cpp:136
The central class of the library. This is the QWidget which displays the plot and interacts with the ...
Definition: qcustomplot.h:1685
void MoveVerticalCrosshair(int units)
MapPlot::MoveVerticalCrosshair.
Definition: mapplot.cpp:206
QCPLayer * layer(const QString &name) const
bool addItem(QCPAbstractItem *item)
QVector< double > qvec
Definition: mapplot.h:28
void CoordinatesChanged(double x, double y, double z)
bool addPlottable(QCPAbstractPlottable *plottable)
QString label() const
void rescaleDataRange(bool recalculateDataBounds=false)
void setTickVector(const QVector< double > &vec)
void SetClusterTicks(size_t count)
Definition: mapplot.cpp:334
void setFont(const QFont &font)
Q_SLOT void setGradient(const QCPColorGradient &gradient)
QCPAxis * keyAxis() const
Definition: qcustomplot.h:1422
void setDataRange(const QCPRange &dataRange)
Definition: mapplot.cpp:268
int keySize() const
Definition: qcustomplot.h:3056
void SetColorScaleTickCount(int ticks)
Definition: mapplot.cpp:319
Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false)
A straight line that spans infinitely in both directions.
Definition: qcustomplot.h:3287
void setTightBoundary(bool enabled)
void setVisible(bool on)
A color scale for use with color coding data such as QCPColorMap.
Definition: qcustomplot.h:2436
MapPlot(QWidget *parent=0)
Definition: mapplot.cpp:22
uword GetCrosshairPosition()
Definition: mapplot.cpp:176
QCPAxis * yAxis2
Definition: qcustomplot.h:1824
QCPAxis * xAxis2
Definition: qcustomplot.h:1824
QCPRange valueRange()
Definition: mapplot.cpp:378
void setKeyRange(const QCPRange &keyRange)
void SpectrumRequested(size_t index)
void setTickVectorLabels(const QVector< QString > &vec)
0x01 Axis is vertical and on the left side of the axis rect
Definition: qcustomplot.h:1047
void SetColorScaleTicks(double min, double max, size_t count)
Definition: mapplot.cpp:324
QCPAxisRect * axisRect(int index=0) const
void setInterpolate(bool enabled)
The QCustomPlot surface is immediately refreshed, by calling QWidget::repaint() after the replot...
Definition: qcustomplot.h:1715
Q_SLOT void setDataRange(const QCPRange &dataRange)
QCPItemPosition *const point1
Definition: qcustomplot.h:3309
void setLabelFont(const QFont &font)
void SaveImage(QString filename)
Definition: mapplot.cpp:246
int valueSize()
Definition: mapplot.cpp:368
double max() const
Definition: mapplot.cpp:197
void rescaleDataRange(bool onlyVisibleMaps=false)
Definition: mapplot.cpp:263
QCPAxis * axis() const
Definition: qcustomplot.h:2454
void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group)
QCPRange keyRange()
Definition: mapplot.cpp:373
A plottable representing a two-dimensional color map in a plot.
Definition: qcustomplot.h:3096
QCPAxis * valueAxis() const
Definition: qcustomplot.h:1423
QCPItemPosition *const point2
Definition: qcustomplot.h:3310
void SetGlobalColorGradient(Vespucci::GlobalGradient gradient)
Definition: mapplot.cpp:126
bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove)
void setValueRange(const QCPRange &valueRange)
Defines a color gradient for use with e.g. QCPColorMap.
Definition: qcustomplot.h:1905
double upper
Definition: qcustomplot.h:484
Represents the range an axis is encompassing.
Definition: qcustomplot.h:481
QCPRange dataRange() const
Definition: qcustomplot.h:3113
void SetColorScaleLabel(const QString &label_text)
Definition: mapplot.cpp:308
double lower
Definition: qcustomplot.h:484
Holds multiple axes and arranges them in a rectangular shape.
Definition: qcustomplot.h:2022
QCPAxis * yAxis
Definition: qcustomplot.h:1824
QCPLegend * legend
Definition: qcustomplot.h:1825
Q_SLOT void setRange(const QCPRange &range)
void setLabel(const QString &str)
void setPen(const QPen &pen)
bool SavePlot(QCustomPlot *plot, QString filename)
Vespucci::SavePlot.
Definition: global.cpp:30
int keySize()
Definition: mapplot.cpp:363