-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plot 2d-image like data as heatmap #52
Merged
Merged
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
234f8b8
[plotwidget] call suggested_plotter only once
gicmo 51aa42a
[git] ignore .idea/
gicmo a67dfd3
[imageplotter] new plotter for image/heatmap data
gicmo 449901d
[plotwidget] integrate imageplotter
gicmo c2d0ae6
[imageplotter] use SampleDimension::axis()
gicmo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ NixView.pro.user.18 | |
NixView.pro.user.3.2-pre1 | ||
NixView.pro.user.5e84e8a | ||
*~ | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
#include "imageplotter.h" | ||
#include "ui_imageplotter.h" | ||
#include <QMenu> | ||
|
||
|
||
ImagePlotter::ImagePlotter(QWidget *parent) : | ||
QWidget(parent), ui(new Ui::ImagePlotter), cmap() { | ||
ui->setupUi(this); | ||
|
||
} | ||
|
||
ImagePlotter::~ImagePlotter() { | ||
delete ui; | ||
} | ||
|
||
QCustomPlot *ImagePlotter::get_plot() { | ||
return ui->plot; | ||
} | ||
|
||
struct DimInfo { | ||
bool valid; | ||
QString unit; | ||
QString label; | ||
|
||
QVector<double> ticks; | ||
QCPRange range; | ||
}; | ||
|
||
static DimInfo get_dim_info(const nix::DataArray &array, nix::ndsize_t dim_index) { | ||
nix::Dimension d = array.getDimension(dim_index); | ||
DimInfo info; | ||
info.valid = false; | ||
|
||
nix::NDSize shape = array.dataExtent(); | ||
|
||
if (d.dimensionType() == nix::DimensionType::Sample) { | ||
nix::SampledDimension dim = d.asSampledDimension(); | ||
info.valid = true; | ||
info.label = dim.label().get_value_or("").c_str(); | ||
info.unit = dim.unit().get_value_or("").c_str(); | ||
double si = dim.samplingInterval(); | ||
//todo: safe cast? | ||
info.ticks.resize(static_cast<int>(shape[dim_index-1])); | ||
|
||
double offset = dim.offset().get_value_or(0); | ||
const int size = info.ticks.size(); | ||
for (int i = 0; i < size; i++) { | ||
info.ticks[i] = offset + i * si; | ||
} | ||
|
||
} else if (d.dimensionType() == nix::DimensionType::Range) { | ||
nix::RangeDimension dim = d.asRangeDimension(); | ||
info.valid = true; | ||
info.label = dim.label().get_value_or("").c_str(); | ||
info.unit = dim.unit().get_value_or("").c_str(); | ||
|
||
info.ticks = QVector<double>::fromStdVector(dim.ticks()); | ||
} | ||
|
||
const int size = info.ticks.size(); | ||
if (size > 0) { | ||
info.range.lower = info.ticks[0]; | ||
info.range.upper = info.ticks[size - 1]; | ||
} | ||
|
||
return info; | ||
} | ||
|
||
void ImagePlotter::draw(const nix::DataArray &array) { | ||
if (array.dimensionCount() != 2) { | ||
std::cerr << "ImagePlotter::draw can only draw 2D!" << std::endl; | ||
return; | ||
} | ||
|
||
DimInfo yi = get_dim_info(array, 1); // rows == y | ||
DimInfo xi = get_dim_info(array, 2); // cols == x | ||
|
||
if (!(yi.valid && xi.valid)) { | ||
std::cerr << "ImagePlotter::invalid dimensions found in array!" << std::endl; | ||
return; | ||
} | ||
|
||
QCustomPlot *plot = get_plot(); | ||
|
||
plot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom); // this will also allow rescaling the color scale by dragging/zooming | ||
plot->axisRect()->setupFullAxesBox(true); | ||
plot->xAxis->setLabel(xi.label + " " + xi.unit); | ||
plot->yAxis->setLabel(yi.label + " " + yi.unit); | ||
|
||
QCPColorMap *colorMap = new QCPColorMap(plot->xAxis, plot->yAxis); | ||
plot->addPlottable(colorMap); | ||
|
||
int nx = xi.ticks.size(); | ||
int ny = yi.ticks.size(); | ||
|
||
colorMap->data()->setSize(nx, ny); | ||
colorMap->data()->setRange(xi.range, yi.range); | ||
colorMap->setInterpolate(false); | ||
|
||
for (int xidx = 0; xidx < nx; xidx++) { | ||
std::vector<double> data(static_cast<size_t>(nx)); | ||
//lets fetch a whole row (should be fast if data is | ||
// row-major, like hdf5) | ||
//ny, the number of rows in data-array | ||
//xidx, the current column the fetch | ||
// -> fetch all rows at column [xidx] | ||
// count offset | ||
array.getData(data, {ny, 1}, {0, xidx}); | ||
for (int yidx = 0; yidx < ny; yidx++) { | ||
// data[ydix], the data point of the row[yidx], col[xidx] | ||
colorMap->data()->setCell(xidx, yidx, data[yidx]); | ||
} | ||
} | ||
|
||
QCPColorScale *colorScale = new QCPColorScale(plot); | ||
plot->plotLayout()->addElement(0, 1, colorScale); | ||
colorScale->setType(QCPAxis::atRight); | ||
colorMap->setColorScale(colorScale); | ||
if (array.label()) { | ||
colorScale->axis()->setLabel(array.label().get().c_str()); | ||
} | ||
colorMap->setGradient(QCPColorGradient::gpSpectrum); | ||
colorMap->rescaleDataRange(); | ||
|
||
QCPMarginGroup *marginGroup = new QCPMarginGroup(plot); | ||
plot->axisRect()->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup); | ||
colorScale->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup); | ||
|
||
plot->rescaleAxes(); | ||
} | ||
|
||
|
||
void ImagePlotter::add_events(const QVector<double> &x_data, const QVector<double> &y_data, const QString &name, | ||
bool y_scale) { | ||
|
||
} | ||
|
||
void ImagePlotter::add_segments(const QVector<double> &positions, const QVector<double> &extents, const QString &name) { | ||
|
||
} | ||
|
||
void ImagePlotter::set_label(const std::string &label) { | ||
|
||
} | ||
|
||
PlotterType ImagePlotter::plotter_type() const { | ||
return PlotterType::Image; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#ifndef IMAGEPLOTTER_H | ||
#define IMAGEPLOTTER_H | ||
|
||
#include <QWidget> | ||
#include "plotter.h" | ||
#include <nix.hpp> | ||
#include "colormap.hpp" | ||
|
||
namespace Ui { | ||
class ImagePlotter; | ||
} | ||
|
||
class ImagePlotter : public QWidget, public Plotter { | ||
Q_OBJECT | ||
public: | ||
|
||
virtual void add_events(const QVector<double> &x_data, const QVector<double> &y_data, const QString &name, | ||
bool y_scale) override; | ||
|
||
virtual void add_segments(const QVector<double> &positions, const QVector<double> &extents, | ||
const QString &name) override; | ||
|
||
virtual void set_label(const std::string &label) override; | ||
|
||
virtual PlotterType plotter_type() const override; | ||
|
||
|
||
public: | ||
explicit ImagePlotter(QWidget *parent = 0); | ||
~ImagePlotter(); | ||
|
||
void draw(const nix::DataArray &array); | ||
|
||
private: | ||
Ui::ImagePlotter *ui; | ||
ColorMap cmap; | ||
|
||
QCustomPlot* get_plot(); | ||
}; | ||
|
||
#endif //IMAGEPLOTTER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ui version="4.0"> | ||
<class>ImagePlotter</class> | ||
<widget class="QWidget" name="ImagePlotter"> | ||
<property name="geometry"> | ||
<rect> | ||
<x>0</x> | ||
<y>0</y> | ||
<width>400</width> | ||
<height>300</height> | ||
</rect> | ||
</property> | ||
<property name="sizePolicy"> | ||
<sizepolicy hsizetype="Ignored" vsizetype="Ignored"> | ||
<horstretch>0</horstretch> | ||
<verstretch>0</verstretch> | ||
</sizepolicy> | ||
</property> | ||
<property name="windowTitle"> | ||
<string>Form</string> | ||
</property> | ||
<property name="autoFillBackground"> | ||
<bool>false</bool> | ||
</property> | ||
<property name="styleSheet"> | ||
<string notr="true"/> | ||
</property> | ||
<layout class="QVBoxLayout" name="verticalLayout"> | ||
<property name="spacing"> | ||
<number>3</number> | ||
</property> | ||
<property name="leftMargin"> | ||
<number>0</number> | ||
</property> | ||
<property name="topMargin"> | ||
<number>0</number> | ||
</property> | ||
<property name="rightMargin"> | ||
<number>0</number> | ||
</property> | ||
<property name="bottomMargin"> | ||
<number>0</number> | ||
</property> | ||
<item> | ||
<widget class="QCustomPlot" name="plot" native="true"> | ||
<property name="sizePolicy"> | ||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> | ||
<horstretch>0</horstretch> | ||
<verstretch>0</verstretch> | ||
</sizepolicy> | ||
</property> | ||
</widget> | ||
</item> | ||
</layout> | ||
</widget> | ||
<customwidgets> | ||
<customwidget> | ||
<class>QCustomPlot</class> | ||
<extends>QWidget</extends> | ||
<header>qcustomplot.h</header> | ||
<container>1</container> | ||
</customwidget> | ||
</customwidgets> | ||
<resources/> | ||
<connections/> | ||
</ui> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could have asked
should have given the same result
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boah, I didn't know about
SampledDimension.axis()
. Cool, I will change that.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
saves you the offset issues