├── setup.cfg ├── .gitmodules ├── helper.h ├── examples ├── plots │ ├── main.py │ ├── mainwindow.ui │ └── mainwindow.py ├── example2.py └── example1.py ├── README.md ├── axistickerdatetime.sip ├── selectionrect.sip ├── axistickertime.sip ├── LICENSE.txt ├── axistickertext.sip ├── axisticker.sip ├── range.sip ├── vector2d.sip ├── .gitignore ├── painter.sip ├── all.sip ├── lineending.sip ├── layer.sip ├── layoutelement-textelement.sip ├── plottable1d.sip ├── selection.sip ├── qmap_double.sip ├── plottable-curve.sip ├── layoutelement-axisrect.sip ├── plottable-graph.sip ├── plottable.sip ├── scatterstyle.sip ├── layoutelement-legend.sip ├── plottable-bars.sip ├── colorgradient.sip ├── setup.py ├── global.sip ├── layout.sip ├── axis.sip ├── core.sip └── item.sip /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "QCustomPlot"] 2 | path = QCustomPlot 3 | url = https://gitlab.com/Corbelli/QCustomPlot.git 4 | branch = repaint_all 5 | -------------------------------------------------------------------------------- /helper.h: -------------------------------------------------------------------------------- 1 | #if !defined(__QCUSTOMPLOT_SIP_HELPER) 2 | #define __QCUSTOMPLOT_SIP_HELPER 3 | 4 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPGraphData; 5 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPBarsData; 6 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPCurveData; 7 | 8 | #endif // __QCUSTOMPLOT_SIP_HELPER 9 | -------------------------------------------------------------------------------- /examples/plots/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # PyQt5 binding for QCustomPlot v2.0.0 5 | # 6 | # Authors: Dmitry Voronin, Giuseppe Corbelli 7 | # License: MIT 8 | # 9 | # QCustomPlot author: Emanuel Eichhammer 10 | # QCustomPlot Website/Contact: http://www.qcustomplot.com 11 | 12 | import sys 13 | 14 | from PyQt5.QtWidgets import QApplication 15 | 16 | import mainwindow 17 | 18 | def main(): 19 | app = QApplication(sys.argv) 20 | # First argument can be a number that specifies loaded example 21 | w = mainwindow.MainWindow(sys.argv) 22 | w.show() 23 | return app.exec_() 24 | 25 | 26 | if __name__ == '__main__': 27 | sys.exit(main()) 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QCustomPlot-PyQt5 2 | Bindings for graphics lib QCustomPlot for PyQt5. 3 | 4 | ## Requirements: 5 | - PyQt5 6 | - sip 7 | - qmake (Qt5) 8 | - make/nmake/jom 9 | - Linux/Windows operating systems 10 | - gcc/msvc compilers 11 | 12 | ## Build & install: 13 | Currently QCustomPlot is statically linked and downloaded as GIT submodule. 14 | 15 | - git submodule update --init 16 | - python setup.py build && sudo python setup.py install 17 | 18 | ## Arguments for build_ext option: 19 | * --qmake -- Path to qmake for building QCustomPlot static library (default: detected from PyQt5 installation) 20 | * --make -- Path to make utility (default: nmake.exe on Windows, make elsewhere) 21 | * --qt-include-dir -- Path to Qt's include location (default: detected from PyQt5 installation) 22 | 23 | ## TODO: 24 | - No debug builds are currently supported 25 | - Test on other than Linux & Windows systems 26 | - Test on compilers other than gcc/MSVC and specify minimum versions 27 | -------------------------------------------------------------------------------- /axistickerdatetime.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPAxisTickerDateTime : public QCPAxisTicker 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | QCPAxisTickerDateTime(); 17 | 18 | // getters: 19 | QString dateTimeFormat() const; 20 | Qt::TimeSpec dateTimeSpec() const; 21 | 22 | // setters: 23 | void setDateTimeFormat(const QString &format); 24 | void setDateTimeSpec(Qt::TimeSpec spec); 25 | void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen) 26 | void setTickOrigin(const QDateTime &origin); 27 | 28 | // static methods: 29 | static QDateTime keyToDateTime(double key); 30 | static double dateTimeToKey(const QDateTime dateTime); 31 | static double dateTimeToKey(const QDate date); 32 | }; 33 | -------------------------------------------------------------------------------- /examples/plots/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 548 10 | 420 11 | 12 | 13 | 14 | QCustomPlot plot examples 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | QCustomPlot 29 | QWidget 30 |
QCustomPlot
31 | 1 32 |
33 |
34 | 35 | 36 |
37 | -------------------------------------------------------------------------------- /selectionrect.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPSelectionRect : public QCPLayerable 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | QCPSelectionRect(QCustomPlot *parentPlot /TransferThis/); 17 | virtual ~QCPSelectionRect(); 18 | 19 | // getters: 20 | QRect rect() const; 21 | QCPRange range(const QCPAxis *axis) const; 22 | QPen pen() const; 23 | QBrush brush() const; 24 | bool isActive() const; 25 | 26 | // setters: 27 | void setPen(const QPen &pen); 28 | void setBrush(const QBrush &brush); 29 | 30 | // non-property methods: 31 | Q_SLOT void cancel(); 32 | 33 | signals: 34 | void started(QMouseEvent *event); 35 | void changed(const QRect &rect, QMouseEvent *event); 36 | void canceled(const QRect &rect, QInputEvent *event); 37 | void accepted(const QRect &rect, QMouseEvent *event); 38 | }; 39 | -------------------------------------------------------------------------------- /axistickertime.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPAxisTickerTime : public QCPAxisTicker 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) 18 | ,tuSeconds ///< Seconds (%%s in \ref setTimeFormat) 19 | ,tuMinutes ///< Minutes (%%m in \ref setTimeFormat) 20 | ,tuHours ///< Hours (%%h in \ref setTimeFormat) 21 | ,tuDays ///< Days (%%d in \ref setTimeFormat) 22 | }; 23 | 24 | QCPAxisTickerTime(); 25 | 26 | // getters: 27 | QString timeFormat(); 28 | int fieldWidth(TimeUnit unit); 29 | 30 | // setters: 31 | void setTimeFormat(const QString &format); 32 | void setFieldWidth(TimeUnit unit, int width); 33 | }; 34 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2019 Dmitry Voronin, Giuseppe Corbelli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /axistickertext.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | %Include qmap_double.sip 11 | 12 | class QCPAxisTickerText : public QCPAxisTicker 13 | { 14 | %TypeHeaderCode 15 | #include 16 | %End 17 | public: 18 | QCPAxisTickerText(); 19 | 20 | // getters: 21 | // This DOES NOT return a reference as it does in C++ version 22 | // Cannot mark as const as the base C++ method is not 23 | QMap ticks(); 24 | int subTickCount() const; 25 | 26 | // setters: 27 | void setTicks(const QMap &ticks); 28 | void setTicks(const QVector &positions, const QVector &labels); 29 | void setSubTickCount(int subTicks); 30 | 31 | // non-virtual methods: 32 | void clear(); 33 | void addTick(double position, const QString &label); 34 | void addTicks(const QMap &ticks); 35 | void addTicks(const QVector &positions, const QVector &labels); 36 | }; 37 | -------------------------------------------------------------------------------- /axisticker.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPAxisTicker 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | enum TickStepStrategy 18 | { 19 | tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount) 20 | ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count 21 | }; 22 | 23 | QCPAxisTicker(); 24 | virtual ~QCPAxisTicker(); 25 | 26 | // getters: 27 | TickStepStrategy tickStepStrategy() const; 28 | int tickCount() const; 29 | double tickOrigin() const; 30 | 31 | // setters: 32 | void setTickStepStrategy(TickStepStrategy strategy); 33 | void setTickCount(int count); 34 | void setTickOrigin(double origin); 35 | 36 | // introduced virtual methods: 37 | virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector &ticks, QVector *subTicks, QVector *tickLabels); 38 | 39 | private: 40 | QCPAxisTicker(const QCPAxisTicker&); 41 | QCPAxisTicker& operator=(const QCPAxisTicker&); 42 | }; 43 | -------------------------------------------------------------------------------- /range.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPRange 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | 16 | public: 17 | double lower; 18 | double upper; 19 | 20 | QCPRange(); 21 | QCPRange(double lower, double upper); 22 | 23 | bool operator==(const QCPRange& other) const; 24 | bool operator!=(const QCPRange& other) const; 25 | 26 | QCPRange &operator+=(const double& value); 27 | QCPRange &operator-=(const double& value); 28 | QCPRange &operator*=(const double& value); 29 | QCPRange &operator/=(const double& value); 30 | 31 | double size() const; 32 | double center() const; 33 | void normalize(); 34 | void expand(const QCPRange &otherRange); 35 | void expand(double includeCoord); 36 | QCPRange expanded(const QCPRange &otherRange) const; 37 | QCPRange expanded(double includeCoord) const; 38 | QCPRange bounded(double lowerBound, double upperBound) const; 39 | QCPRange sanitizedForLogScale() const; 40 | QCPRange sanitizedForLinScale() const; 41 | bool contains(double value) const; 42 | 43 | static bool validRange(double lower, double upper); 44 | static bool validRange(const QCPRange &range); 45 | static const double minRange; 46 | static const double maxRange; 47 | }; 48 | -------------------------------------------------------------------------------- /vector2d.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPVector2D 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | QCPVector2D(); 17 | QCPVector2D(double x, double y); 18 | QCPVector2D(const QPoint &point); 19 | QCPVector2D(const QPointF &point); 20 | 21 | // getters: 22 | double x() const; 23 | double y() const; 24 | 25 | // setters: 26 | void setX(double x); 27 | void setY(double y); 28 | 29 | // non-virtual methods: 30 | double length() const; 31 | double lengthSquared() const; 32 | QPoint toPoint() const; 33 | QPointF toPointF() const; 34 | 35 | bool isNull() const; 36 | void normalize(); 37 | QCPVector2D normalized() const; 38 | QCPVector2D perpendicular() const; 39 | double dot(const QCPVector2D &vec) const; 40 | double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; 41 | double distanceSquaredToLine(const QLineF &line) const; 42 | double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; 43 | 44 | QCPVector2D &operator*=(double factor); 45 | QCPVector2D &operator/=(double divisor); 46 | QCPVector2D &operator+=(const QCPVector2D &vector); 47 | QCPVector2D &operator-=(const QCPVector2D &vector); 48 | }; 49 | -------------------------------------------------------------------------------- /examples/example2.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from PyQt5.QtCore import Qt 3 | from PyQt5.QtWidgets import QApplication 4 | from PyQt5.QtGui import QColor, QPen 5 | from qcustomplot import QCustomPlot, QCPBars, QCP, QCPBarsGroup 6 | 7 | 8 | if __name__ == '__main__': 9 | 10 | app = QApplication(sys.argv) 11 | 12 | w = QCustomPlot() 13 | 14 | datax = [1, 2, 3, 4, 5] 15 | datay1 = [0.6, 0.5, 0.3, 0.15, 2.] 16 | datay2 = [0.3, 0.28, 0.2, 0.1, 3.] 17 | datay3 = [0.33, 0.31, 0.27, 0.13, 4.] 18 | 19 | group = QCPBarsGroup(w) 20 | bars1 = QCPBars(w.xAxis, w.yAxis) 21 | w.addPlottable(bars1) 22 | bars1.setData(datax, datay1) 23 | bars1.setBrush(QColor(0, 0, 255, 50)) 24 | bars1.setPen(QColor(0, 0, 255)) 25 | bars1.setWidth(0.15) 26 | bars1.setBarsGroup(group) 27 | 28 | bars2 = QCPBars(w.xAxis, w.yAxis) 29 | w.addPlottable(bars2) 30 | bars2.setData(datax, datay2) 31 | bars2.setBrush(QColor(180, 00, 120, 50)) 32 | bars2.setPen(QColor(180, 00, 120)) 33 | bars2.setWidth(0.15) 34 | bars2.setBarsGroup(group) 35 | 36 | bars3 = QCPBars(w.xAxis, w.yAxis) 37 | w.addPlottable(bars3) 38 | bars3.setData(datax, datay3) 39 | bars3.setBrush(QColor(255, 154, 0, 50)) 40 | bars3.setPen(QColor(255, 154, 0)) 41 | bars3.setWidth(0.15) 42 | bars3.setBarsGroup(group) 43 | 44 | w.xAxis.setRange(0.1, 4.9) 45 | w.yAxis.setRange(0, 0.7) 46 | w.xAxis.setAutoTickStep(False) 47 | w.xAxis.setTickStep(1) 48 | w.show() 49 | 50 | sys.exit(app.exec()) 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | 93 | # Rope project settings 94 | .ropeproject 95 | 96 | # mkdocs documentation 97 | /site 98 | 99 | -------------------------------------------------------------------------------- /painter.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPPainter : public QPainter 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices 17 | ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. 18 | ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels 19 | ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) 20 | }; 21 | typedef QFlags PainterModes; 22 | 23 | QCPPainter(); 24 | explicit QCPPainter(QPaintDevice *device); 25 | 26 | // getters: 27 | bool antialiasing() const; 28 | PainterModes modes() const; 29 | 30 | // setters: 31 | void setAntialiasing(bool enabled); 32 | void setMode(PainterMode mode, bool enabled=true); 33 | void setModes(PainterModes modes); 34 | 35 | // methods hiding non-virtual base class functions (QPainter bug workarounds): 36 | bool begin(QPaintDevice *device); 37 | void setPen(const QPen &pen); 38 | void setPen(const QColor &color); 39 | void setPen(Qt::PenStyle penStyle); 40 | void drawLine(const QLineF &line); 41 | void drawLine(const QPointF &p1, const QPointF &p2); 42 | void save(); 43 | void restore(); 44 | 45 | // non-virtual methods: 46 | void makeNonCosmetic(); 47 | }; 48 | -------------------------------------------------------------------------------- /all.sip: -------------------------------------------------------------------------------- 1 | %Copying 2 | PyQt5 binding for QCustomPlot v2.0.0 3 | 4 | Authors: Dmitry Voronin, Giuseppe Corbelli 5 | License: MIT 6 | 7 | QCustomPlot author: Emanuel Eichhammer 8 | QCustomPlot Website/Contact: http://www.qcustomplot.com 9 | %End 10 | 11 | %Module QCustomPlot 12 | 13 | 14 | %Import QtCore/QtCoremod.sip 15 | %Import QtGui/QtGuimod.sip 16 | %Import QtWidgets/QtWidgetsmod.sip 17 | 18 | // Include order taken from qcp.h 19 | %Include global.sip 20 | %Include vector2d.sip 21 | %Include painter.sip 22 | // #include "paintbuffer.h" 23 | %Include layer.sip 24 | %Include range.sip 25 | %Include selection.sip 26 | %Include selectionrect.sip 27 | %Include layout.sip 28 | %Include lineending.sip 29 | %Include axisticker.sip 30 | %Include axistickerdatetime.sip 31 | %Include axistickertext.sip 32 | %Include axistickertime.sip 33 | //#include "axis/axistickerfixed.h" 34 | //#include "axis/axistickerpi.h" 35 | //#include "axis/axistickerlog.h" 36 | %Include axis.sip 37 | %Include scatterstyle.sip 38 | //%Include datacontainer.sip 39 | %Include plottable.sip 40 | %Include item.sip 41 | %Include core.sip 42 | %Include plottable1d.sip 43 | %Include colorgradient.sip 44 | //#include "selectiondecorator-bracket.h" 45 | %Include layoutelement-axisrect.sip 46 | %Include layoutelement-legend.sip 47 | %Include layoutelement-textelement.sip 48 | //#include "layoutelements/layoutelement-colorscale.h" 49 | %Include plottable-graph.sip 50 | %Include plottable-curve.sip 51 | %Include plottable-bars.sip 52 | //#include "plottables/plottable-statisticalbox.h" 53 | //#include "plottables/plottable-colormap.h" 54 | //#include "plottables/plottable-financial.h" 55 | //#include "plottables/plottable-errorbar.h" 56 | //#include "items/item-straightline.h" 57 | //#include "items/item-line.h" 58 | //#include "items/item-curve.h" 59 | //#include "items/item-rect.h" 60 | //#include "items/item-text.h" 61 | //#include "items/item-ellipse.h" 62 | //#include "items/item-pixmap.h" 63 | //#include "items/item-tracer.h" 64 | //#include "items/item-bracket.h" 65 | -------------------------------------------------------------------------------- /lineending.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPLineEnding 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | enum EndingStyle { esNone ///< No ending decoration 17 | ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) 18 | ,esSpikeArrow ///< A filled arrow head with an indented back 19 | ,esLineArrow ///< A non-filled arrow head with open back 20 | ,esDisc ///< A filled circle 21 | ,esSquare ///< A filled square 22 | ,esDiamond ///< A filled diamond (45 degrees rotated square) 23 | ,esBar ///< A bar perpendicular to the line 24 | ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) 25 | ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) 26 | }; 27 | 28 | QCPLineEnding(); 29 | QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); 30 | 31 | // getters: 32 | EndingStyle style() const; 33 | double width() const; 34 | double length() const; 35 | bool inverted() const; 36 | 37 | // setters: 38 | void setStyle(EndingStyle style); 39 | void setWidth(double width); 40 | void setLength(double length); 41 | void setInverted(bool inverted); 42 | 43 | // non-property methods: 44 | double boundingDistance() const; 45 | double realLength() const; 46 | void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const; 47 | void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; 48 | }; 49 | -------------------------------------------------------------------------------- /layer.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPLayer : public QObject 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers. 18 | ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot). 19 | }; 20 | 21 | QCPLayer(QCustomPlot* parentPlot /TransferThis/, const QString &layerName); 22 | virtual ~QCPLayer(); 23 | 24 | // getters: 25 | QCustomPlot *parentPlot() const; 26 | QString name() const; 27 | int index() const; 28 | QList children() const; 29 | bool visible() const; 30 | LayerMode mode() const; 31 | 32 | // setters: 33 | void setVisible(bool visible); 34 | void setMode(LayerMode mode); 35 | 36 | // non-virtual methods: 37 | void replot(); 38 | }; 39 | 40 | class QCPLayerable : public QObject /Abstract/ 41 | { 42 | %TypeHeaderCode 43 | #include 44 | %End 45 | public: 46 | QCPLayerable(QCustomPlot* plot /TransferThis/, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); 47 | virtual ~QCPLayerable(); 48 | 49 | // getters: 50 | bool visible() const; 51 | QCustomPlot *parentPlot() const; 52 | QCPLayerable *parentLayerable() const; 53 | QCPLayer *layer() const; 54 | bool antialiased() const; 55 | 56 | // setters: 57 | void setVisible(bool on); 58 | Q_SLOT bool setLayer(QCPLayer *layer); 59 | bool setLayer(const QString &layerName); 60 | void setAntialiased(bool enabled); 61 | 62 | // introduced virtual methods: 63 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 64 | 65 | // non-property methods: 66 | bool realVisibility() const; 67 | 68 | signals: 69 | void layerChanged(QCPLayer *newLayer); 70 | }; 71 | -------------------------------------------------------------------------------- /layoutelement-textelement.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPTextElement : public QCPLayoutElement /NoDefaultCtors/ 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | explicit QCPTextElement(QCustomPlot *parentPlot); 18 | QCPTextElement(QCustomPlot *parentPlot /TransferThis/, const QString &text); 19 | QCPTextElement(QCustomPlot *parentPlot /TransferThis/, const QString &text, double pointSize); 20 | QCPTextElement(QCustomPlot *parentPlot /TransferThis/, const QString &text, const QString &fontFamily, double pointSize); 21 | QCPTextElement(QCustomPlot *parentPlot /TransferThis/, const QString &text, const QFont &font); 22 | 23 | // getters: 24 | QString text() const; 25 | int textFlags() const; 26 | QFont font() const; 27 | QColor textColor() const; 28 | QFont selectedFont() const; 29 | QColor selectedTextColor() const; 30 | bool selectable() const; 31 | bool selected() const; 32 | 33 | // setters: 34 | void setText(const QString &text); 35 | void setTextFlags(int flags); 36 | void setFont(const QFont &font); 37 | void setTextColor(const QColor &color); 38 | void setSelectedFont(const QFont &font); 39 | void setSelectedTextColor(const QColor &color); 40 | Q_SLOT void setSelectable(bool selectable); 41 | Q_SLOT void setSelected(bool selected); 42 | 43 | // reimplemented virtual methods: 44 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 45 | virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); 46 | virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); 47 | virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); 48 | 49 | signals: 50 | void selectionChanged(bool selected); 51 | void selectableChanged(bool selectable); 52 | void clicked(QMouseEvent *event); 53 | void doubleClicked(QMouseEvent *event); 54 | }; 55 | -------------------------------------------------------------------------------- /plottable1d.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPPlottableInterface1D /Abstract/ 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | virtual ~QCPPlottableInterface1D(); 17 | // introduced pure virtual methods: 18 | virtual int dataCount() const = 0; 19 | virtual double dataMainKey(int index) const = 0; 20 | virtual double dataSortKey(int index) const = 0; 21 | virtual double dataMainValue(int index) const = 0; 22 | virtual QCPRange dataValueRange(int index) const = 0; 23 | virtual QPointF dataPixelPosition(int index) const = 0; 24 | virtual bool sortKeyIsMainKey() const = 0; 25 | virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; 26 | virtual int findBegin(double sortKey, bool expandedRange=true) const = 0; 27 | virtual int findEnd(double sortKey, bool expandedRange=true) const = 0; 28 | }; 29 | 30 | template 31 | class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D /Abstract/ 32 | { 33 | %TypeHeaderCode 34 | #include 35 | #include "helper.h" 36 | %End 37 | public: 38 | QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); 39 | virtual ~QCPAbstractPlottable1D(); 40 | 41 | // virtual methods of 1d plottable interface: 42 | virtual int dataCount() const; 43 | virtual double dataMainKey(int index) const; 44 | virtual double dataSortKey(int index) const; 45 | virtual double dataMainValue(int index) const; 46 | virtual QCPRange dataValueRange(int index) const; 47 | virtual QPointF dataPixelPosition(int index) const; 48 | virtual bool sortKeyIsMainKey() const; 49 | virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const; 50 | virtual int findBegin(double sortKey, bool expandedRange=true) const; 51 | virtual int findEnd(double sortKey, bool expandedRange=true) const; 52 | 53 | // reimplemented virtual methods: 54 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 55 | virtual QCPPlottableInterface1D *interface1D(); 56 | }; 57 | -------------------------------------------------------------------------------- /selection.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPDataRange 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | QCPDataRange(); 17 | QCPDataRange(int begin, int end); 18 | 19 | bool operator==(const QCPDataRange& other) const; 20 | bool operator!=(const QCPDataRange& other) const; 21 | 22 | // getters: 23 | int begin() const; 24 | int end() const; 25 | int size() const; 26 | int length() const; 27 | 28 | // setters: 29 | void setBegin(int begin); 30 | void setEnd(int end) ; 31 | 32 | // non-property methods: 33 | bool isValid() const; 34 | bool isEmpty() const; 35 | QCPDataRange bounded(const QCPDataRange &other) const; 36 | QCPDataRange expanded(const QCPDataRange &other) const; 37 | QCPDataRange intersection(const QCPDataRange &other) const; 38 | QCPDataRange adjusted(int changeBegin, int changeEnd) const; 39 | bool intersects(const QCPDataRange &other) const; 40 | bool contains(const QCPDataRange &other) const; 41 | }; 42 | 43 | 44 | class QCPDataSelection 45 | { 46 | %TypeHeaderCode 47 | #include 48 | %End 49 | public: 50 | explicit QCPDataSelection(); 51 | explicit QCPDataSelection(const QCPDataRange &range); 52 | 53 | bool operator==(const QCPDataSelection& other) const; 54 | bool operator!=(const QCPDataSelection& other) const; 55 | QCPDataSelection &operator+=(const QCPDataSelection& other); 56 | QCPDataSelection &operator+=(const QCPDataRange& other); 57 | QCPDataSelection &operator-=(const QCPDataSelection& other); 58 | QCPDataSelection &operator-=(const QCPDataRange& other); 59 | 60 | // getters: 61 | int dataRangeCount() const; 62 | int dataPointCount() const; 63 | QCPDataRange dataRange(int index=0) const; 64 | QList dataRanges() const; 65 | QCPDataRange span() const; 66 | 67 | // non-property methods: 68 | void addDataRange(const QCPDataRange &dataRange, bool simplify=true); 69 | void clear(); 70 | bool isEmpty() const; 71 | void simplify(); 72 | void enforceType(QCP::SelectionType type); 73 | bool contains(const QCPDataSelection &other) const; 74 | QCPDataSelection intersection(const QCPDataRange &other) const; 75 | QCPDataSelection intersection(const QCPDataSelection &other) const; 76 | QCPDataSelection inverse(const QCPDataRange &outerRange) const; 77 | }; 78 | -------------------------------------------------------------------------------- /examples/example1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from PyQt5.QtCore import Qt 3 | from PyQt5.QtWidgets import QApplication 4 | from PyQt5.QtGui import QColor, QPen 5 | from qcustomplot import QCustomPlot, QCPBars, QCP 6 | 7 | 8 | if __name__ == '__main__': 9 | 10 | app = QApplication(sys.argv) 11 | 12 | w = QCustomPlot() 13 | regen = QCPBars(w.xAxis, w.yAxis) 14 | nuclear = QCPBars(w.xAxis, w.yAxis) 15 | fossil = QCPBars(w.xAxis, w.yAxis) 16 | 17 | w.addPlottable(regen) 18 | w.addPlottable(nuclear) 19 | w.addPlottable(fossil) 20 | 21 | pen = QPen() 22 | pen.setWidthF(1.2) 23 | fossil.setName('Fossil fuels') 24 | pen.setColor(QColor(255, 131, 0)) 25 | fossil.setPen(pen) 26 | fossil.setBrush(QColor(255, 131, 0, 50)) 27 | nuclear.setName('Nuclear') 28 | pen.setColor(QColor(1, 92, 192)) 29 | nuclear.setPen(pen) 30 | nuclear.setBrush(QColor(1, 92, 191, 50)) 31 | regen.setName('Regenerative') 32 | pen.setColor(QColor(150, 222, 0)) 33 | regen.setPen(pen) 34 | regen.setBrush(QColor(150, 222, 0, 70)) 35 | nuclear.moveAbove(fossil) 36 | regen.moveAbove(nuclear) 37 | 38 | ticks = [1, 2, 3, 4, 5, 6, 7] 39 | labels = ['USA', 'Japan', 'Germany', 'France', 'UK', 'Italy', 'Canada'] 40 | w.xAxis.setAutoTicks(False) 41 | w.xAxis.setAutoTickLabels(False) 42 | w.xAxis.setTickVector(ticks) 43 | w.xAxis.setTickVectorLabels(labels) 44 | w.xAxis.setTickLabelRotation(60) 45 | w.xAxis.setSubTickCount(0) 46 | w.xAxis.grid().setVisible(True) 47 | w.xAxis.setRange(0, 8) 48 | 49 | w.yAxis.setRange(0, 12.1) 50 | w.yAxis.setPadding(5) 51 | w.yAxis.setLabel('Power Consumption in\nKilowatts per Capita (2007)') 52 | w.yAxis.grid().setSubGridVisible(True) 53 | 54 | grid_pen = QPen() 55 | grid_pen.setStyle(Qt.SolidLine) 56 | grid_pen.setColor(QColor(0, 0, 0, 25)) 57 | w.yAxis.grid().setSubGridPen(grid_pen) 58 | 59 | fossil_data = [0.86 * 10.5, 0.83 * 5.5, 0.84 * 5.5, 0.52 * 5.8, 0.89 * 5.2, 0.90 * 4.2, 0.67 * 11.2] 60 | nuclear_data = [0.08 * 10.5, 0.12 * 5.5, 0.12 * 5.5, 0.40 * 5.8, 0.09 * 5.2, 0.00 * 4.2, 0.07 * 11.2] 61 | regen_data = [0.06 * 10.5, 0.05 * 5.5, 0.04 * 5.5, 0.06 * 5.8, 0.02 * 5.2, 0.07 * 4.2, 0.25 * 11.2] 62 | fossil.setData(ticks, fossil_data) 63 | nuclear.setData(ticks, nuclear_data) 64 | regen.setData(ticks, regen_data) 65 | 66 | w.legend.setVisible(True) 67 | w.axisRect().insetLayout().setInsetAlignment(0, Qt.AlignTop|Qt.AlignHCenter) 68 | w.legend.setBrush(QColor(255, 255, 255, 200)) 69 | legendPen = QPen() 70 | legendPen.setColor(QColor(130, 130, 130, 200)) 71 | w.legend.setBorderPen(legendPen) 72 | w.setInteractions(QCP.iRangeDrag or QCP.iRangeZoom) 73 | 74 | w.show() 75 | 76 | sys.exit(app.exec()) 77 | -------------------------------------------------------------------------------- /qmap_double.sip: -------------------------------------------------------------------------------- 1 | // QMap is implemented as a Python dictionary. 2 | 3 | template 4 | %MappedType QMap /TypeHint="Dict[float, _TYPE_]", TypeHintValue="{}"/ 5 | { 6 | %TypeHeaderCode 7 | #include 8 | %End 9 | 10 | %ConvertFromTypeCode 11 | // Create the dictionary. 12 | PyObject *d = PyDict_New(); 13 | 14 | if (!d) 15 | return NULL; 16 | 17 | // Set the dictionary elements. 18 | QMap::const_iterator it = sipCpp->constBegin(); 19 | 20 | while (it != sipCpp->constEnd()) 21 | { 22 | PyObject *kobj = PyFloat_FromDouble(it.key()); 23 | if (!kobj) { 24 | Py_DECREF(d); 25 | return NULL; 26 | } 27 | 28 | _TYPE_ *v = new _TYPE_(it.value()); 29 | PyObject *vobj = sipConvertFromNewType(v, sipType__TYPE_, sipTransferObj); 30 | if (!vobj) { 31 | delete v; 32 | Py_DECREF(kobj); 33 | Py_DECREF(d); 34 | return NULL; 35 | } 36 | 37 | int rc = PyDict_SetItem(d, kobj, vobj); 38 | Py_DECREF(vobj); 39 | Py_DECREF(kobj); 40 | if (rc < 0) { 41 | Py_DECREF(d); 42 | return NULL; 43 | } 44 | ++it; 45 | } 46 | return d; 47 | %End 48 | 49 | %ConvertToTypeCode 50 | if (!sipIsErr) 51 | return PyDict_Check(sipPy); 52 | 53 | QMap *qm = new QMap; 54 | 55 | Py_ssize_t pos = 0; 56 | PyObject *kobj, *vobj; 57 | 58 | while (PyDict_Next(sipPy, &pos, &kobj, &vobj)) { 59 | double k {PyFloat_AS_DOUBLE(kobj)}; 60 | 61 | if (PyErr_Occurred()) 62 | { 63 | if (PyErr_ExceptionMatches(PyExc_TypeError)) 64 | PyErr_Format(PyExc_TypeError, 65 | "a dict key has type '%s' but 'double' is expected", 66 | sipPyTypeName(Py_TYPE(kobj))); 67 | 68 | delete qm; 69 | *sipIsErr = 1; 70 | 71 | return 0; 72 | } 73 | 74 | int vstate; 75 | _TYPE_ *v = reinterpret_cast<_TYPE_ *>( 76 | sipForceConvertToType(vobj, sipType__TYPE_, sipTransferObj, 77 | SIP_NOT_NONE, &vstate, sipIsErr)); 78 | 79 | if (*sipIsErr) 80 | { 81 | PyErr_Format(PyExc_TypeError, 82 | "a dict value has type '%s' but '_TYPE_' is expected", 83 | sipPyTypeName(Py_TYPE(vobj))); 84 | 85 | delete qm; 86 | 87 | return 0; 88 | } 89 | 90 | qm->insert(k, *v); 91 | 92 | sipReleaseType(v, sipType__TYPE_, vstate); 93 | } 94 | 95 | *sipCppPtr = qm; 96 | 97 | return sipGetState(sipTransferObj); 98 | %End 99 | }; 100 | -------------------------------------------------------------------------------- /plottable-curve.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPCurveData 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | QCPCurveData(); 18 | QCPCurveData(double t, double key, double value); 19 | 20 | double sortKey() const; 21 | static QCPCurveData fromSortKey(double sortKey); 22 | static bool sortKeyIsMainKey(); 23 | 24 | double mainKey() const; 25 | double mainValue() const; 26 | 27 | QCPRange valueRange() const; 28 | 29 | double t; 30 | double key; 31 | double value; 32 | }; 33 | 34 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPCurveData; 35 | 36 | class QCPCurve : public QCPAbstractPlottable1D_QCPCurveData 37 | { 38 | %TypeHeaderCode 39 | #include 40 | 41 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPCurveData; 42 | %End 43 | public: 44 | enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) 45 | ,lsLine ///< Data points are connected with a straight line 46 | }; 47 | 48 | // Ownership acquired by QCustomPlot tied to the axis 49 | explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) /Transfer/; 50 | virtual ~QCPCurve(); 51 | 52 | // getters: 53 | // TODO: provide methodcode 54 | // QSharedPointer data() const { return mDataContainer; } 55 | QCPScatterStyle scatterStyle() const; 56 | int scatterSkip() const; 57 | LineStyle lineStyle() const; 58 | 59 | // setters: 60 | // TODO: provide methodcode 61 | // void setData(QSharedPointer data); 62 | void setData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); 63 | void setData(const QVector &keys, const QVector &values); 64 | void setScatterStyle(const QCPScatterStyle &style); 65 | void setScatterSkip(int skip); 66 | void setLineStyle(LineStyle style); 67 | 68 | // non-property methods: 69 | void addData(const QVector &t, const QVector &keys, const QVector &values, bool alreadySorted=false); 70 | void addData(const QVector &keys, const QVector &values); 71 | void addData(double t, double key, double value); 72 | void addData(double key, double value); 73 | 74 | // reimplemented virtual methods: 75 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 76 | virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const; 77 | virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const; 78 | 79 | //! This is not in QCustomPlot, but I found it handy 80 | Q_SLOT void setSelected(bool selected); 81 | %MethodCode 82 | Py_BEGIN_ALLOW_THREADS 83 | QCPDataSelection current_selection = sipCpp->selection(); 84 | if (a0) 85 | current_selection += sipCpp->data()->dataRange(); 86 | else 87 | current_selection.clear(); 88 | 89 | sipCpp->setSelection(current_selection); 90 | Py_END_ALLOW_THREADS 91 | %End 92 | }; 93 | -------------------------------------------------------------------------------- /layoutelement-axisrect.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPAxisRect : public QCPLayoutElement 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | explicit QCPAxisRect(QCustomPlot *parentPlot /TransferThis/, bool setupDefaultAxes=true); 18 | virtual ~QCPAxisRect(); 19 | 20 | // getters: 21 | QPixmap background() const; 22 | QBrush backgroundBrush() const; 23 | bool backgroundScaled() const; 24 | Qt::AspectRatioMode backgroundScaledMode() const; 25 | Qt::Orientations rangeDrag() const; 26 | Qt::Orientations rangeZoom() const; 27 | QCPAxis *rangeDragAxis(Qt::Orientation orientation); 28 | QCPAxis *rangeZoomAxis(Qt::Orientation orientation); 29 | QList rangeDragAxes(Qt::Orientation orientation); 30 | QList rangeZoomAxes(Qt::Orientation orientation); 31 | double rangeZoomFactor(Qt::Orientation orientation); 32 | 33 | // setters: 34 | void setBackground(const QPixmap &pm); 35 | void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); 36 | void setBackground(const QBrush &brush); 37 | void setBackgroundScaled(bool scaled); 38 | void setBackgroundScaledMode(Qt::AspectRatioMode mode); 39 | void setRangeDrag(Qt::Orientations orientations); 40 | void setRangeZoom(Qt::Orientations orientations); 41 | void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); 42 | void setRangeDragAxes(QList axes); 43 | void setRangeDragAxes(QList horizontal, QList vertical); 44 | void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); 45 | void setRangeZoomAxes(QList axes); 46 | void setRangeZoomAxes(QList horizontal, QList vertical); 47 | void setRangeZoomFactor(double horizontalFactor, double verticalFactor); 48 | void setRangeZoomFactor(double factor); 49 | 50 | // non-property methods: 51 | int axisCount(QCPAxis::AxisType type) const; 52 | QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; 53 | QList axes(QCPAxis::AxisTypes types) const; 54 | QList axes() const; 55 | QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); 56 | QList addAxes(QCPAxis::AxisTypes types); 57 | bool removeAxis(QCPAxis *axis); 58 | QCPLayoutInset *insetLayout() const; 59 | 60 | void zoom(const QRectF &pixelRect); 61 | void zoom(const QRectF &pixelRect, const QList &affectedAxes); 62 | void setupFullAxesBox(bool connectRanges=false); 63 | QList plottables() const; 64 | QList graphs() const; 65 | QList items() const; 66 | 67 | // read-only interface imitating a QRect: 68 | int left() const; 69 | int right() const; 70 | int top() const; 71 | int bottom() const; 72 | int width() const; 73 | int height() const; 74 | QSize size() const; 75 | QPoint topLeft() const; 76 | QPoint topRight() const; 77 | QPoint bottomLeft() const; 78 | QPoint bottomRight() const; 79 | QPoint center() const; 80 | 81 | // reimplemented virtual methods: 82 | virtual void update(UpdatePhase phase); 83 | virtual QList elements(bool recursive) const; 84 | }; 85 | -------------------------------------------------------------------------------- /plottable-graph.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPGraphData 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | QCPGraphData(); 18 | QCPGraphData(double key, double value); 19 | 20 | double sortKey() const; 21 | static QCPGraphData fromSortKey(double sortKey); 22 | static bool sortKeyIsMainKey(); 23 | 24 | double mainKey() const; 25 | double mainValue() const; 26 | 27 | QCPRange valueRange() const; 28 | 29 | double key; 30 | double value; 31 | }; 32 | 33 | 34 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPGraphData; 35 | 36 | class QCPGraph : public QCPAbstractPlottable1D_QCPGraphData 37 | { 38 | %TypeHeaderCode 39 | #include 40 | 41 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPGraphData; 42 | %End 43 | public: 44 | enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented 45 | ///< with symbols according to the scatter style, see \ref setScatterStyle) 46 | ,lsLine ///< data points are connected by a straight line 47 | ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point 48 | ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point 49 | ,lsStepCenter ///< line is drawn as steps where the step is in between two data points 50 | ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line 51 | }; 52 | 53 | explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); 54 | virtual ~QCPGraph(); 55 | 56 | // getters: 57 | // TODO: provide methodcode 58 | // QSharedPointer data() const; 59 | LineStyle lineStyle() const; 60 | QCPScatterStyle scatterStyle() const; 61 | int scatterSkip() const; 62 | QCPGraph *channelFillGraph() const; 63 | bool adaptiveSampling() const; 64 | 65 | // setters: 66 | // TODO: provide methodcode 67 | // void setData(QSharedPointer data); 68 | void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); 69 | void setLineStyle(LineStyle ls); 70 | void setScatterStyle(const QCPScatterStyle &style); 71 | void setScatterSkip(int skip); 72 | void setChannelFillGraph(QCPGraph *targetGraph); 73 | void setAdaptiveSampling(bool enabled); 74 | 75 | // non-property methods: 76 | void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); 77 | void addData(double key, double value); 78 | 79 | // reimplemented virtual methods: 80 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 81 | virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const; 82 | virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const; 83 | 84 | //! This is not in QCustomPlot, but I found it handy 85 | Q_SLOT void setSelected(bool selected); 86 | %MethodCode 87 | Py_BEGIN_ALLOW_THREADS 88 | QCPDataSelection current_selection = sipCpp->selection(); 89 | if (a0) 90 | current_selection += sipCpp->data()->dataRange(); 91 | else 92 | current_selection.clear(); 93 | 94 | sipCpp->setSelection(current_selection); 95 | Py_END_ALLOW_THREADS 96 | %End 97 | }; 98 | -------------------------------------------------------------------------------- /plottable.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPSelectionDecorator /NoDefaultCtors/ 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | QCPSelectionDecorator(); 17 | virtual ~QCPSelectionDecorator(); 18 | 19 | // getters: 20 | QPen pen() const; 21 | QBrush brush() const; 22 | QCPScatterStyle scatterStyle() const; 23 | QCPScatterStyle::ScatterProperties usedScatterProperties() const; 24 | 25 | // setters: 26 | void setPen(const QPen &pen); 27 | void setBrush(const QBrush &brush); 28 | void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen); 29 | void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); 30 | 31 | // non-virtual methods: 32 | void applyPen(QCPPainter *painter) const; 33 | void applyBrush(QCPPainter *painter) const; 34 | QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; 35 | 36 | // introduced virtual methods: 37 | virtual void copyFrom(const QCPSelectionDecorator *other); 38 | virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); 39 | }; 40 | 41 | 42 | class QCPAbstractPlottable : public QCPLayerable /Abstract/ 43 | { 44 | %TypeHeaderCode 45 | #include 46 | %End 47 | public: 48 | QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); 49 | virtual ~QCPAbstractPlottable(); 50 | 51 | // getters: 52 | QString name() const; 53 | bool antialiasedFill() const; 54 | bool antialiasedScatters() const; 55 | QPen pen() const; 56 | QBrush brush() const; 57 | QCPAxis *keyAxis() const; 58 | QCPAxis *valueAxis() const; 59 | QCP::SelectionType selectable() const; 60 | bool selected() const; 61 | QCPDataSelection selection() const; 62 | QCPSelectionDecorator *selectionDecorator() const; 63 | 64 | // setters: 65 | void setName(const QString &name); 66 | void setAntialiasedFill(bool enabled); 67 | void setAntialiasedScatters(bool enabled); 68 | void setPen(const QPen &pen); 69 | void setBrush(const QBrush &brush); 70 | void setKeyAxis(QCPAxis *axis); 71 | void setValueAxis(QCPAxis *axis); 72 | Q_SLOT void setSelectable(QCP::SelectionType selectable); 73 | Q_SLOT void setSelection(QCPDataSelection selection); 74 | void setSelectionDecorator(QCPSelectionDecorator *decorator /Transfer/); 75 | 76 | // introduced virtual methods: 77 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; 78 | virtual QCPPlottableInterface1D *interface1D(); 79 | virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0; 80 | virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0; 81 | 82 | // non-property methods: 83 | const QPointF coordsToPixels(double key, double value) const; 84 | void pixelsToCoords(double x, double y, double &key, double &value) const; 85 | void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; 86 | void rescaleAxes(bool onlyEnlarge=false) const; 87 | void rescaleKeyAxis(bool onlyEnlarge=false) const; 88 | void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const; 89 | bool addToLegend(QCPLegend *legend); 90 | bool addToLegend(); 91 | bool removeFromLegend(QCPLegend *legend) const; 92 | bool removeFromLegend() const; 93 | 94 | signals: 95 | void selectionChanged(bool selected); 96 | void selectionChanged(const QCPDataSelection &selection); 97 | void selectableChanged(QCP::SelectionType selectable); 98 | }; 99 | -------------------------------------------------------------------------------- /scatterstyle.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPScatterStyle 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | enum ScatterProperty { spNone = 0x00 ///< 0x00 None 17 | ,spPen = 0x01 ///< 0x01 The pen property, see \ref setPen 18 | ,spBrush = 0x02 ///< 0x02 The brush property, see \ref setBrush 19 | ,spSize = 0x04 ///< 0x04 The size property, see \ref setSize 20 | ,spShape = 0x08 ///< 0x08 The shape property, see \ref setShape 21 | ,spAll = 0xFF ///< 0xFF All properties 22 | }; 23 | typedef QFlags ScatterProperties; 24 | 25 | enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) 26 | ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) 27 | ,ssCross ///< \enumimage{ssCross.png} a cross 28 | ,ssPlus ///< \enumimage{ssPlus.png} a plus 29 | ,ssCircle ///< \enumimage{ssCircle.png} a circle 30 | ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) 31 | ,ssSquare ///< \enumimage{ssSquare.png} a square 32 | ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond 33 | ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus 34 | ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline 35 | ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner 36 | ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside 37 | ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside 38 | ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside 39 | ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside 40 | ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines 41 | ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates 42 | ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) 43 | }; 44 | 45 | QCPScatterStyle(); 46 | QCPScatterStyle(ScatterShape shape, double size=6); 47 | QCPScatterStyle(ScatterShape shape, const QColor &color, double size); 48 | QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); 49 | QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); 50 | QCPScatterStyle(const QPixmap &pixmap); 51 | QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); 52 | 53 | // getters: 54 | double size() const; 55 | ScatterShape shape() const; 56 | QPen pen() const; 57 | QBrush brush() const; 58 | QPixmap pixmap() const; 59 | QPainterPath customPath() const; 60 | 61 | // setters: 62 | void setFromOther(const QCPScatterStyle &other, ScatterProperties properties); 63 | void setSize(double size); 64 | void setShape(ScatterShape shape); 65 | void setPen(const QPen &pen); 66 | void setBrush(const QBrush &brush); 67 | void setPixmap(const QPixmap &pixmap); 68 | void setCustomPath(const QPainterPath &customPath); 69 | 70 | // non-property methods: 71 | bool isNone() const; 72 | bool isPenDefined() const; 73 | void undefinePen(); 74 | void applyTo(QCPPainter *painter, const QPen &defaultPen) const; 75 | void drawShape(QCPPainter *painter, const QPointF &pos) const; 76 | void drawShape(QCPPainter *painter, double x, double y) const; 77 | }; 78 | -------------------------------------------------------------------------------- /layoutelement-legend.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPAbstractLegendItem : public QCPLayoutElement /Abstract/ 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | explicit QCPAbstractLegendItem(QCPLegend *parent /TransferThis/); 17 | 18 | // getters: 19 | QCPLegend *parentLegend() const; 20 | QFont font() const; 21 | QColor textColor() const; 22 | QFont selectedFont() const; 23 | QColor selectedTextColor() const; 24 | bool selectable() const; 25 | bool selected() const; 26 | 27 | // setters: 28 | void setFont(const QFont &font); 29 | void setTextColor(const QColor &color); 30 | void setSelectedFont(const QFont &font); 31 | void setSelectedTextColor(const QColor &color); 32 | Q_SLOT void setSelectable(bool selectable); 33 | Q_SLOT void setSelected(bool selected); 34 | 35 | // reimplemented virtual methods: 36 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 37 | 38 | signals: 39 | void selectionChanged(bool selected); 40 | void selectableChanged(bool selectable); 41 | }; 42 | 43 | 44 | class QCPPlottableLegendItem : public QCPAbstractLegendItem 45 | { 46 | %TypeHeaderCode 47 | #include 48 | %End 49 | public: 50 | QCPPlottableLegendItem(QCPLegend *parent /TransferThis/, QCPAbstractPlottable *plottable); 51 | 52 | // getters: 53 | QCPAbstractPlottable *plottable(); 54 | }; 55 | 56 | 57 | class QCPLegend : public QCPLayoutGrid 58 | { 59 | %TypeHeaderCode 60 | #include 61 | %End 62 | public: 63 | enum SelectablePart { spNone = 0x000 ///< 0x000 None 64 | ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) 65 | ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) 66 | }; 67 | typedef QFlags SelectableParts; 68 | 69 | explicit QCPLegend(); 70 | virtual ~QCPLegend(); 71 | 72 | // getters: 73 | QPen borderPen() const; 74 | QBrush brush() const; 75 | QFont font() const; 76 | QColor textColor() const; 77 | QSize iconSize() const; 78 | int iconTextPadding() const; 79 | QPen iconBorderPen() const; 80 | SelectableParts selectableParts() const; 81 | SelectableParts selectedParts() const; 82 | QPen selectedBorderPen() const; 83 | QPen selectedIconBorderPen() const; 84 | QBrush selectedBrush() const; 85 | QFont selectedFont() const; 86 | QColor selectedTextColor() const; 87 | 88 | // setters: 89 | void setBorderPen(const QPen &pen); 90 | void setBrush(const QBrush &brush); 91 | void setFont(const QFont &font); 92 | void setTextColor(const QColor &color); 93 | void setIconSize(const QSize &size); 94 | void setIconSize(int width, int height); 95 | void setIconTextPadding(int padding); 96 | void setIconBorderPen(const QPen &pen); 97 | Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); 98 | Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); 99 | void setSelectedBorderPen(const QPen &pen); 100 | void setSelectedIconBorderPen(const QPen &pen); 101 | void setSelectedBrush(const QBrush &brush); 102 | void setSelectedFont(const QFont &font); 103 | void setSelectedTextColor(const QColor &color); 104 | 105 | // reimplemented virtual methods: 106 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 107 | 108 | // non-virtual methods: 109 | QCPAbstractLegendItem *item(int index) const; 110 | QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; 111 | int itemCount() const; 112 | bool hasItem(QCPAbstractLegendItem *item) const; 113 | bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; 114 | bool addItem(QCPAbstractLegendItem *item); 115 | bool removeItem(int index); 116 | bool removeItem(QCPAbstractLegendItem *item); 117 | void clearItems(); 118 | QList selectedItems() const; 119 | 120 | signals: 121 | void selectionChanged(QCPLegend::SelectableParts parts); 122 | void selectableChanged(QCPLegend::SelectableParts parts); 123 | }; 124 | -------------------------------------------------------------------------------- /plottable-bars.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | class QCPBarsGroup : public QObject 11 | { 12 | %TypeHeaderCode 13 | #include 14 | %End 15 | public: 16 | enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels 17 | ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size 18 | ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range 19 | }; 20 | 21 | QCPBarsGroup(QCustomPlot *parentPlot /TransferThis/); 22 | virtual ~QCPBarsGroup(); 23 | 24 | // getters: 25 | SpacingType spacingType() const; 26 | double spacing() const; 27 | 28 | // setters: 29 | void setSpacingType(SpacingType spacingType); 30 | void setSpacing(double spacing); 31 | 32 | // non-virtual methods: 33 | QList bars() const; 34 | QCPBars* bars(int index) const; 35 | int size() const; 36 | bool isEmpty() const; 37 | void clear(); 38 | bool contains(QCPBars *bars) const; 39 | void append(QCPBars *bars); 40 | void insert(int i, QCPBars *bars); 41 | void remove(QCPBars *bars); 42 | }; 43 | 44 | 45 | class QCPBarsData 46 | { 47 | %TypeHeaderCode 48 | #include 49 | 50 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPBarsData; 51 | %End 52 | public: 53 | QCPBarsData(); 54 | QCPBarsData(double key, double value); 55 | 56 | double sortKey() const; 57 | static QCPBarsData fromSortKey(double sortKey); 58 | static bool sortKeyIsMainKey(); 59 | 60 | double mainKey() const; 61 | double mainValue() const; 62 | 63 | QCPRange valueRange() const; // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here 64 | 65 | double key; 66 | double value; 67 | }; 68 | 69 | 70 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPBarsData; 71 | 72 | class QCPBars : public QCPAbstractPlottable1D_QCPBarsData 73 | { 74 | %TypeHeaderCode 75 | #include 76 | 77 | typedef QCPAbstractPlottable1D QCPAbstractPlottable1D_QCPBarsData; 78 | %End 79 | 80 | public: 81 | enum WidthType { wtAbsolute ///< Bar width is in absolute pixels 82 | ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size 83 | ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range 84 | }; 85 | 86 | // TODO: Technically ownership is trasferred to keyAxis->parentPlot() 87 | explicit QCPBars(QCPAxis *keyAxis /TransferThis/, QCPAxis *valueAxis); 88 | virtual ~QCPBars(); 89 | 90 | // getters: 91 | double width() const; 92 | WidthType widthType() const; 93 | QCPBarsGroup *barsGroup() const; 94 | double baseValue() const; 95 | double stackingGap() const; 96 | QCPBars *barBelow() const; 97 | QCPBars *barAbove() const; 98 | // TODO: provide methodcode 99 | // QSharedPointer data() const; 100 | 101 | // setters: 102 | // TODO: provide methodcode 103 | // void setData(QSharedPointer data); 104 | void setData(const QVector &keys, const QVector &values, bool alreadySorted=false); 105 | void setWidth(double width); 106 | void setWidthType(WidthType widthType); 107 | void setBarsGroup(QCPBarsGroup *barsGroup); 108 | void setBaseValue(double baseValue); 109 | void setStackingGap(double pixels); 110 | 111 | // non-property methods: 112 | void addData(const QVector &keys, const QVector &values, bool alreadySorted=false); 113 | void addData(double key, double value); 114 | void moveBelow(QCPBars *bars); 115 | void moveAbove(QCPBars *bars); 116 | 117 | // reimplemented virtual methods: 118 | virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const; 119 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 120 | virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const; 121 | virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const; 122 | virtual QPointF dataPixelPosition(int index) const; 123 | 124 | //! This is not in QCustomPlot, but I found it handy 125 | Q_SLOT void setSelected(bool selected); 126 | %MethodCode 127 | Py_BEGIN_ALLOW_THREADS 128 | QCPDataSelection current_selection = sipCpp->selection(); 129 | if (a0) 130 | current_selection += sipCpp->data()->dataRange(); 131 | else 132 | current_selection.clear(); 133 | 134 | sipCpp->setSelection(current_selection); 135 | Py_END_ALLOW_THREADS 136 | %End 137 | }; 138 | 139 | 140 | -------------------------------------------------------------------------------- /colorgradient.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | %MappedType QMap 12 | { 13 | %TypeHeaderCode 14 | // Include the library interface to the type being mapped. 15 | #include 16 | #include 17 | %End 18 | 19 | %ConvertFromTypeCode 20 | PyObject *d = PyDict_New(); 21 | 22 | if (!d) 23 | return 0; 24 | 25 | QMap::const_iterator it = sipCpp->constBegin(); 26 | QMap::const_iterator end = sipCpp->constEnd(); 27 | 28 | while (it != end) 29 | { 30 | PyObject *kobj = PyFloat_FromDouble(it.key()); 31 | 32 | if (!kobj) 33 | { 34 | Py_DECREF(d); 35 | return 0; 36 | } 37 | 38 | QColor *v = new QColor(it.value()); 39 | PyObject *vobj = sipConvertFromNewType(v, sipType_QColor, 40 | sipTransferObj); 41 | 42 | if (!vobj) 43 | { 44 | delete v; 45 | Py_DECREF(kobj); 46 | Py_DECREF(d); 47 | return 0; 48 | } 49 | 50 | int rc = PyDict_SetItem(d, kobj, vobj); 51 | 52 | Py_DECREF(vobj); 53 | Py_DECREF(kobj); 54 | 55 | if (rc < 0) 56 | { 57 | Py_DECREF(d); 58 | return 0; 59 | } 60 | 61 | ++it; 62 | } 63 | 64 | return d; 65 | %End 66 | 67 | %ConvertToTypeCode 68 | if (!sipIsErr) 69 | return PyDict_Check(sipPy); 70 | 71 | QMap *qm = new QMap; 72 | 73 | SIP_SSIZE_T pos = 0; 74 | PyObject *kobj, *vobj; 75 | 76 | while (PyDict_Next(sipPy, &pos, &kobj, &vobj)) 77 | { 78 | PyErr_Clear(); 79 | double k = PyFloat_AsDouble(kobj); 80 | 81 | if (PyErr_Occurred()) 82 | { 83 | PyErr_Format(PyExc_TypeError, 84 | "a key has type '%s' but 'float' is expected", 85 | Py_TYPE(kobj)->tp_name); 86 | 87 | delete qm; 88 | *sipIsErr = 1; 89 | 90 | return 0; 91 | } 92 | 93 | int vstate; 94 | QColor* v = reinterpret_cast( 95 | sipForceConvertToType( 96 | vobj, sipType_QColor, sipTransferObj, SIP_NOT_NONE, &vstate, sipIsErr 97 | ) 98 | ); 99 | 100 | if (*sipIsErr) 101 | { 102 | PyErr_Format(PyExc_TypeError, 103 | "a value has type '%s' but 'QColor' is expected", 104 | Py_TYPE(vobj)->tp_name); 105 | sipReleaseType(v, sipType_QColor, vstate); 106 | delete qm; 107 | return 0; 108 | } 109 | 110 | qm->insert(k, *v); 111 | 112 | sipReleaseType(v, sipType_QColor, vstate); 113 | } 114 | 115 | *sipCppPtr = qm; 116 | 117 | return sipGetState(sipTransferObj); 118 | %End 119 | }; 120 | 121 | 122 | class QCPColorGradient 123 | { 124 | %TypeHeaderCode 125 | #include 126 | %End 127 | public: 128 | enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated 129 | ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) 130 | }; 131 | 132 | enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) 133 | ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) 134 | ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) 135 | ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) 136 | ,gpCandy ///< Blue over pink to white 137 | ,gpGeography ///< Colors suitable to represent different elevations on geographical maps 138 | ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) 139 | ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white 140 | ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values 141 | ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) 142 | ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) 143 | ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) 144 | }; 145 | 146 | QCPColorGradient(); 147 | QCPColorGradient(GradientPreset preset); 148 | bool operator==(const QCPColorGradient &other) const; 149 | bool operator!=(const QCPColorGradient &other) const; 150 | 151 | // getters: 152 | int levelCount() const; 153 | QMap colorStops() const; 154 | ColorInterpolation colorInterpolation() const; 155 | bool periodic() const; 156 | 157 | // setters: 158 | void setLevelCount(int n); 159 | void setColorStops(const QMap &colorStops); 160 | void setColorStopAt(double position, const QColor &color); 161 | void setColorInterpolation(ColorInterpolation interpolation); 162 | void setPeriodic(bool enabled); 163 | 164 | // non-property methods: 165 | void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); 166 | void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); 167 | QRgb color(double position, const QCPRange &range, bool logarithmic=false); 168 | void loadPreset(GradientPreset preset); 169 | void clearColorStops(); 170 | QCPColorGradient inverted() const; 171 | }; 172 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | import platform 5 | import subprocess 6 | 7 | import sipconfig 8 | 9 | from distutils.core import DistutilsError 10 | from distutils.ccompiler import CCompiler 11 | from distutils.sysconfig import customize_compiler 12 | from os.path import join, exists, abspath, dirname 13 | 14 | from setuptools import setup, Extension 15 | 16 | from sipdistutils import build_ext 17 | 18 | from PyQt5.QtCore import PYQT_CONFIGURATION 19 | from PyQt5.QtCore import QLibraryInfo 20 | 21 | # monkey-patch for parallel compilation, see 22 | # https://stackoverflow.com/questions/11013851/speeding-up-build-process-with-distutils 23 | def parallelCCompile(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): 24 | # those lines are copied from distutils.ccompiler.CCompiler directly 25 | macros, objects, extra_postargs, pp_opts, build = self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) 26 | cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) 27 | # parallel code 28 | N = os.cpu_count() # number of parallel compilations 29 | import multiprocessing.pool 30 | def _single_compile(obj): 31 | try: src, ext = build[obj] 32 | except KeyError: return 33 | self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) 34 | # convert to list, imap is evaluated on-demand 35 | list(multiprocessing.pool.ThreadPool(N).imap(_single_compile,objects)) 36 | return objects 37 | 38 | 39 | WINDOWS_HOST = (platform.system() == 'Windows') 40 | LINUX_HOST = (platform.system() == 'Linux') 41 | 42 | # This is with Unix pathsep even on windows 43 | QT_BINARIES = QLibraryInfo.location(QLibraryInfo.BinariesPath) 44 | if WINDOWS_HOST: 45 | # Default to MSVC nmake 46 | DEFAULT_MAKE = 'jom.exe' 47 | DEFAULT_QMAKE = "{}/{}".format(QT_BINARIES, "qmake.exe") 48 | else: 49 | DEFAULT_MAKE = 'make' 50 | DEFAULT_QMAKE = "{}/{}".format(QT_BINARIES, "qmake") 51 | 52 | DEFAULT_QT_INCLUDE = QLibraryInfo.location(QLibraryInfo.HeadersPath) 53 | ROOT = abspath(dirname(__file__)) 54 | BUILD_STATIC_DIR = join(ROOT, 'lib-static') 55 | 56 | # Monkey-patch, see above 57 | CCompiler.compile=parallelCCompile 58 | 59 | 60 | class MyBuilderExt(build_ext): 61 | user_options = build_ext.user_options[:] 62 | user_options += [ 63 | ('qmake=', None, 'Path to qmake'), 64 | ('qt-include-dir=', None, 'Path to Qt headers'), 65 | ('qt-library-dir=', None, 'Path to Qt library dir (used at link time)'), 66 | ('make=', None, 'Path to make (either GNU make/nmake/jom)') 67 | ] 68 | 69 | def initialize_options(self): 70 | build_ext.initialize_options(self) 71 | self.qmake = None 72 | self.qt_include_dir = None 73 | self.qt_library_dir = None 74 | self.make = None 75 | self.static_lib = None 76 | pyqt_sip_config = PYQT_CONFIGURATION['sip_flags'] 77 | if self.sip_opts is None: 78 | self.sip_opts = pyqt_sip_config 79 | else: 80 | self.sip_opts += pyqt_sip_config 81 | 82 | def finalize_options(self): 83 | build_ext.finalize_options(self) 84 | if self.qmake is None: 85 | print('Setting qmake to \'%s\'' % DEFAULT_QMAKE) 86 | self.qmake = DEFAULT_QMAKE 87 | if self.make is None: 88 | print('Setting make to \'%s\'' % DEFAULT_MAKE) 89 | self.make = DEFAULT_MAKE 90 | if self.qt_include_dir is None: 91 | pipe = subprocess.Popen([self.qmake, "-query", "QT_INSTALL_HEADERS"], stdout=subprocess.PIPE) 92 | (stdout, stderr) = pipe.communicate() 93 | self.qt_include_dir = str(stdout.strip(), 'utf8') 94 | print('Setting Qt include dir to \'%s\'' % self.qt_include_dir) 95 | 96 | if self.qt_library_dir is None: 97 | pipe = subprocess.Popen([self.qmake, "-query", "QT_INSTALL_LIBS"], stdout=subprocess.PIPE) 98 | (stdout, stderr) = pipe.communicate() 99 | self.qt_library_dir = str(stdout.strip(), 'utf8') 100 | print('Setting Qt library dir to \'%s\'' % self.qt_library_dir) 101 | 102 | if not exists(self.qmake): 103 | raise DistutilsError('Could not determine valid qmake at %s' % self.qmake) 104 | 105 | def __build_qcustomplot_library(self): 106 | if WINDOWS_HOST: 107 | qcustomplot_static = join(self.build_temp, 'release', 'qcustomplot.lib') 108 | else: 109 | qcustomplot_static = join(self.build_temp, 'libqcustomplot.a') 110 | if exists(qcustomplot_static): 111 | return 112 | 113 | os.makedirs(self.build_temp, exist_ok=True) 114 | os.chdir(self.build_temp) 115 | print('Make static qcustomplot library...') 116 | self.spawn([self.qmake, join(ROOT, 'QCustomPlot/src/qcp-staticlib.pro')]) 117 | # AFAIK only nmake does not support -j option 118 | has_multiprocess = not(WINDOWS_HOST and "nmake" in self.make) 119 | make_cmdline = [self.make] 120 | if has_multiprocess: 121 | make_cmdline.extend(('-j', str(os.cpu_count()))) 122 | make_cmdline.append('release') 123 | self.spawn(make_cmdline) 124 | 125 | os.chdir(ROOT) 126 | self.static_lib = qcustomplot_static 127 | # Possibly it's hack 128 | qcustomplot_ext = self.extensions[0] 129 | qcustomplot_ext.extra_objects = [qcustomplot_static] 130 | 131 | def build_extensions(self): 132 | customize_compiler(self.compiler) 133 | try: 134 | self.compiler.compiler_so.remove('-Wstrict-prototypes') 135 | except (AttributeError, ValueError): 136 | pass 137 | self.__build_qcustomplot_library() 138 | # Possibly it's hack 139 | qcustomplot_ext = self.extensions[0] 140 | qcustomplot_ext.include_dirs += [ 141 | join(self.qt_include_dir, subdir) 142 | for subdir in ['.', 'QtCore', 'QtGui', 'QtWidgets', 'QtPrintSupport'] 143 | ] 144 | qcustomplot_ext.library_dirs += [ 145 | self.build_temp, 146 | self.qt_library_dir 147 | ] 148 | 149 | qcustomplot_ext.libraries = [ 150 | 'Qt5Core', 151 | 'Qt5Gui', 152 | 'Qt5Widgets', 153 | 'Qt5PrintSupport', 154 | 'qcustomplot' 155 | ] 156 | 157 | if WINDOWS_HOST: 158 | qcustomplot_ext.library_dirs.append(join(self.build_temp, 'release')) 159 | qcustomplot_ext.libraries.append('Opengl32') 160 | 161 | build_ext.build_extensions(self) 162 | 163 | def _sip_sipfiles_dir(self): 164 | cfg = sipconfig.Configuration() 165 | return join(cfg.default_sip_dir, 'PyQt5') 166 | 167 | setup( 168 | name='QCustomPlot', 169 | version='2.0.3', 170 | description='QCustomPlot is a PyQt5 widget for plotting and data visualization', 171 | author='Dmitry Voronin, Giuseppe Corbelli', 172 | author_email='carriingfate92@yandex.ru', 173 | url='https://github.com/dimv36/QCustomPlot-PyQt5', 174 | platforms=['Linux'], 175 | license='MIT', 176 | ext_modules=[ 177 | Extension( 178 | 'QCustomPlot', 179 | ['all.sip'], 180 | include_dirs=['.'] 181 | ), 182 | ], 183 | requires=[ 184 | 'sipconfig', 185 | 'PyQt5' 186 | ], 187 | cmdclass={'build_ext': MyBuilderExt}, 188 | zip_safe=False 189 | ) 190 | -------------------------------------------------------------------------------- /global.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | namespace QCP 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | 17 | enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) 18 | ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) 19 | ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) 20 | }; 21 | 22 | enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting 23 | ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level) 24 | }; 25 | 26 | enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero 27 | ,sdBoth ///< Both sign domains, including zero, i.e. all numbers 28 | ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero 29 | }; 30 | 31 | enum MarginSide { msLeft = 0x01 ///< 0x01 left margin 32 | ,msRight = 0x02 ///< 0x02 right margin 33 | ,msTop = 0x04 ///< 0x04 top margin 34 | ,msBottom = 0x08 ///< 0x08 bottom margin 35 | ,msAll = 0xFF ///< 0xFF all margins 36 | ,msNone = 0x00 ///< 0x00 no margin 37 | }; 38 | // The Q_DECLARE_FLAGS() macro expands to 39 | // typedef QFlags Flags; 40 | typedef QFlags MarginSides; 41 | 42 | enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks 43 | ,aeGrid = 0x0002 ///< 0x0002 Grid lines 44 | ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines 45 | ,aeLegend = 0x0008 ///< 0x0008 Legend box 46 | ,aeLegendItems = 0x0010 ///< 0x0010 Legend items 47 | ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables 48 | ,aeItems = 0x0040 ///< 0x0040 Main lines of items 49 | ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) 50 | ,aeFills = 0x0100 ///< 0x0100 Borders of fills (e.g. under or between graphs) 51 | ,aeZeroLine = 0x0200 ///< 0x0200 Zero-lines, see \ref QCPGrid::setZeroLinePen 52 | ,aeOther = 0x8000 ///< 0x8000 Other elements that don't fit into any of the existing categories 53 | ,aeAll = 0xFFFF ///< 0xFFFF All elements 54 | ,aeNone = 0x0000 ///< 0x0000 No elements 55 | }; 56 | typedef QFlags AntialiasedElements; 57 | 58 | enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set 59 | ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment 60 | ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens. 61 | ,phImmediateRefresh = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint. 62 | ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). 63 | ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. 64 | }; 65 | typedef QFlags PlottingHints; 66 | 67 | enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) 68 | ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) 69 | ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking 70 | ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) 71 | ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) 72 | ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) 73 | ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) 74 | ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, other layout elements,...) 75 | }; 76 | typedef QFlags Interactions; 77 | 78 | enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging 79 | ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly. 80 | ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.) 81 | ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction. 82 | }; 83 | 84 | enum SelectionType { stNone ///< The plottable is not selectable 85 | ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected. 86 | ,stSingleData ///< One individual data point can be selected at a time 87 | ,stDataRange ///< Multiple contiguous data points (a data range) can be selected 88 | ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected 89 | }; 90 | 91 | bool isInvalidData(double value); 92 | bool isInvalidData(double value1, double value2); 93 | void setMarginValue(QMargins &margins, QCP::MarginSide side, int value); 94 | int getMarginValue(const QMargins &margins, QCP::MarginSide side); 95 | 96 | }; // Namespace QCP 97 | -------------------------------------------------------------------------------- /layout.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPMarginGroup : public QObject 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | 17 | public: 18 | explicit QCPMarginGroup(QCustomPlot *parentPlot /TransferThis/); 19 | virtual ~QCPMarginGroup(); 20 | 21 | // non-virtual methods: 22 | QList elements(QCP::MarginSide side) const; 23 | bool isEmpty() const; 24 | void clear(); 25 | }; 26 | 27 | 28 | class QCPLayoutElement : public QCPLayerable 29 | { 30 | %TypeHeaderCode 31 | #include 32 | %End 33 | 34 | public: 35 | enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout 36 | ,upMargins ///< Phase in which the margins are calculated and set 37 | ,upLayout ///< Final phase in which the layout system places the rects of the elements 38 | }; 39 | 40 | enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect 41 | , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins 42 | }; 43 | 44 | explicit QCPLayoutElement(QCustomPlot *parentPlot /TransferThis/ = 0); 45 | virtual ~QCPLayoutElement(); 46 | 47 | // getters: 48 | QCPLayout *layout() const; 49 | QRect rect() const; 50 | QRect outerRect() const; 51 | QMargins margins() const; 52 | QMargins minimumMargins() const; 53 | QCP::MarginSides autoMargins() const; 54 | QSize minimumSize() const; 55 | QSize maximumSize() const; 56 | SizeConstraintRect sizeConstraintRect() const; 57 | QCPMarginGroup *marginGroup(QCP::MarginSide side) const; 58 | QHash marginGroups() const; 59 | 60 | // setters: 61 | void setOuterRect(const QRect &rect); 62 | void setMargins(const QMargins &margins); 63 | void setMinimumMargins(const QMargins &margins); 64 | void setAutoMargins(QCP::MarginSides sides); 65 | void setMinimumSize(const QSize &size); 66 | void setMinimumSize(int width, int height); 67 | void setMaximumSize(const QSize &size); 68 | void setMaximumSize(int width, int height); 69 | void setSizeConstraintRect(SizeConstraintRect constraintRect); 70 | void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); 71 | 72 | // introduced virtual methods: 73 | virtual void update(UpdatePhase phase); 74 | virtual QSize minimumOuterSizeHint() const; 75 | virtual QSize maximumOuterSizeHint() const; 76 | virtual QList elements(bool recursive) const; 77 | 78 | // reimplemented virtual methods: 79 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 80 | }; 81 | 82 | 83 | class QCPLayout : public QCPLayoutElement 84 | { 85 | %TypeHeaderCode 86 | #include 87 | %End 88 | 89 | public: 90 | explicit QCPLayout(); 91 | 92 | // reimplemented virtual methods: 93 | virtual void update(UpdatePhase phase); 94 | virtual QList elements(bool recursive) const; 95 | 96 | // introduced virtual methods: 97 | virtual int elementCount() const = 0; 98 | virtual QCPLayoutElement* elementAt(int index) const = 0; 99 | virtual QCPLayoutElement* takeAt(int index) = 0; 100 | virtual bool take(QCPLayoutElement* element) = 0; 101 | virtual void simplify(); 102 | 103 | // non-virtual methods: 104 | bool removeAt(int index); 105 | bool remove(QCPLayoutElement* element); 106 | void clear(); 107 | }; 108 | 109 | 110 | class QCPLayoutGrid : public QCPLayout 111 | { 112 | %TypeHeaderCode 113 | #include 114 | %End 115 | 116 | public: 117 | enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap. 118 | ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap. 119 | }; 120 | 121 | explicit QCPLayoutGrid(); 122 | virtual ~QCPLayoutGrid(); 123 | 124 | // getters: 125 | int rowCount() const; 126 | int columnCount() const; 127 | QList columnStretchFactors() const; 128 | QList rowStretchFactors() const; 129 | int columnSpacing() const; 130 | int rowSpacing() const; 131 | int wrap() const; 132 | FillOrder fillOrder() const; 133 | 134 | // setters: 135 | void setColumnStretchFactor(int column, double factor); 136 | void setColumnStretchFactors(const QList &factors); 137 | void setRowStretchFactor(int row, double factor); 138 | void setRowStretchFactors(const QList &factors); 139 | void setColumnSpacing(int pixels); 140 | void setRowSpacing(int pixels); 141 | void setWrap(int count); 142 | void setFillOrder(FillOrder order, bool rearrange=true); 143 | 144 | // reimplemented virtual methods: 145 | virtual void updateLayout() ; 146 | virtual int elementCount() const; 147 | virtual QCPLayoutElement* elementAt(int index) const; 148 | virtual QCPLayoutElement* takeAt(int index); 149 | virtual bool take(QCPLayoutElement* element); 150 | virtual QList elements(bool recursive) const; 151 | virtual void simplify(); 152 | virtual QSize minimumOuterSizeHint() const; 153 | virtual QSize maximumOuterSizeHint() const; 154 | 155 | // non-virtual methods: 156 | QCPLayoutElement *element(int row, int column) const; 157 | bool addElement(int row, int column, QCPLayoutElement *element); 158 | bool addElement(QCPLayoutElement *element); 159 | bool hasElement(int row, int column); 160 | void expandTo(int newRowCount, int newColumnCount); 161 | void insertRow(int newIndex); 162 | void insertColumn(int newIndex); 163 | int rowColToIndex(int row, int column) const; 164 | void indexToRowCol(int index, int &row, int &column) const; 165 | }; 166 | 167 | 168 | class QCPLayoutInset : public QCPLayout 169 | { 170 | %TypeHeaderCode 171 | #include 172 | %End 173 | 174 | public: 175 | enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect 176 | ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment 177 | }; 178 | 179 | explicit QCPLayoutInset(); 180 | virtual ~QCPLayoutInset(); 181 | 182 | // getters: 183 | InsetPlacement insetPlacement(int index) const; 184 | Qt::Alignment insetAlignment(int index) const; 185 | QRectF insetRect(int index) const; 186 | 187 | // setters: 188 | void setInsetPlacement(int index, InsetPlacement placement); 189 | void setInsetAlignment(int index, Qt::Alignment alignment); 190 | void setInsetRect(int index, const QRectF &rect); 191 | 192 | // reimplemented virtual methods: 193 | virtual void updateLayout(); 194 | virtual int elementCount() const; 195 | virtual QCPLayoutElement* elementAt(int index) const; 196 | virtual QCPLayoutElement* takeAt(int index); 197 | virtual bool take(QCPLayoutElement* element); 198 | virtual void simplify(); 199 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 200 | 201 | // non-virtual methods: 202 | void addElement(QCPLayoutElement *element, Qt::Alignment alignment); 203 | void addElement(QCPLayoutElement *element, const QRectF &rect); 204 | }; 205 | -------------------------------------------------------------------------------- /axis.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPGrid :public QCPLayerable 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | explicit QCPGrid(QCPAxis *parentAxis /TransferThis/); 18 | 19 | // getters: 20 | bool subGridVisible() const; 21 | bool antialiasedSubGrid() const; 22 | bool antialiasedZeroLine() const; 23 | QPen pen() const; 24 | QPen subGridPen() const; 25 | QPen zeroLinePen() const; 26 | 27 | // setters: 28 | void setSubGridVisible(bool visible); 29 | void setAntialiasedSubGrid(bool enabled); 30 | void setAntialiasedZeroLine(bool enabled); 31 | void setPen(const QPen &pen); 32 | void setSubGridPen(const QPen &pen); 33 | void setZeroLinePen(const QPen &pen); 34 | }; 35 | 36 | 37 | class QCPAxis : public QCPLayerable 38 | { 39 | %TypeHeaderCode 40 | #include 41 | %End 42 | public: 43 | enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect 44 | ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect 45 | ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect 46 | ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect 47 | }; 48 | typedef QFlags AxisTypes; 49 | 50 | enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect 51 | ,lsOutside ///< Tick labels will be displayed outside the axis rect 52 | }; 53 | 54 | enum ScaleType { stLinear ///< Linear scaling 55 | ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). 56 | }; 57 | 58 | enum SelectablePart { spNone = 0 ///< None of the selectable parts 59 | ,spAxis = 0x001 ///< The axis backbone and tick marks 60 | ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) 61 | ,spAxisLabel = 0x004 ///< The axis label 62 | }; 63 | typedef QFlags SelectableParts; 64 | 65 | explicit QCPAxis(QCPAxisRect *parent /TransferThis/, AxisType type); 66 | virtual ~QCPAxis(); 67 | 68 | // getters: 69 | AxisType axisType() const; 70 | QCPAxisRect *axisRect() const; 71 | ScaleType scaleType() const; 72 | const QCPRange range() const; 73 | bool rangeReversed() const; 74 | QCPAxisTicker* ticker() const; 75 | %MethodCode 76 | sipRes = sipCpp->ticker().data(); 77 | %End 78 | bool ticks() const; 79 | bool tickLabels() const; 80 | int tickLabelPadding() const; 81 | QFont tickLabelFont() const; 82 | QColor tickLabelColor() const; 83 | double tickLabelRotation() const; 84 | LabelSide tickLabelSide() const; 85 | QString numberFormat() const; 86 | int numberPrecision() const; 87 | QVector tickVector() const; 88 | QVector tickVectorLabels() const; 89 | int tickLengthIn() const; 90 | int tickLengthOut() const; 91 | bool subTicks() const; 92 | int subTickLengthIn() const; 93 | int subTickLengthOut() const; 94 | QPen basePen() const; 95 | QPen tickPen() const; 96 | QPen subTickPen() const; 97 | QFont labelFont() const; 98 | QColor labelColor() const; 99 | QString label() const; 100 | int labelPadding() const; 101 | int padding() const; 102 | int offset() const; 103 | SelectableParts selectedParts() const; 104 | SelectableParts selectableParts() const; 105 | QFont selectedTickLabelFont() const; 106 | QFont selectedLabelFont() const; 107 | QColor selectedTickLabelColor() const; 108 | QColor selectedLabelColor() const; 109 | QPen selectedBasePen() const; 110 | QPen selectedTickPen() const; 111 | QPen selectedSubTickPen() const; 112 | QCPLineEnding lowerEnding() const; 113 | QCPLineEnding upperEnding() const; 114 | QCPGrid *grid() const; 115 | 116 | // setters: 117 | Q_SLOT void setScaleType(QCPAxis::ScaleType type); 118 | Q_SLOT void setRange(const QCPRange &range); 119 | void setRange(double lower, double upper); 120 | void setRange(double position, double size, Qt::AlignmentFlag alignment); 121 | void setRangeLower(double lower); 122 | void setRangeUpper(double upper); 123 | void setRangeReversed(bool reversed); 124 | void setTicker(QCPAxisTicker* ticker /Transfer/); 125 | %Docstring(format = "deindented", signature = "prepended") 126 | Set a new ticker on the axis. Ownership of the ticker is transferred to the axis 127 | and cannot be taken back. 128 | %End 129 | %MethodCode 130 | sipCpp->setTicker(QSharedPointer(a0)); 131 | %End 132 | void setTicks(bool show); 133 | void setTickLabels(bool show); 134 | void setTickLabelPadding(int padding); 135 | void setTickLabelFont(const QFont &font); 136 | void setTickLabelColor(const QColor &color); 137 | void setTickLabelRotation(double degrees); 138 | void setTickLabelSide(LabelSide side); 139 | void setNumberFormat(const QString &formatCode); 140 | void setNumberPrecision(int precision); 141 | void setTickLength(int inside, int outside=0); 142 | void setTickLengthIn(int inside); 143 | void setTickLengthOut(int outside); 144 | void setSubTicks(bool show); 145 | void setSubTickLength(int inside, int outside=0); 146 | void setSubTickLengthIn(int inside); 147 | void setSubTickLengthOut(int outside); 148 | void setBasePen(const QPen &pen); 149 | void setTickPen(const QPen &pen); 150 | void setSubTickPen(const QPen &pen); 151 | void setLabelFont(const QFont &font); 152 | void setLabelColor(const QColor &color); 153 | void setLabel(const QString &str); 154 | void setLabelPadding(int padding); 155 | void setPadding(int padding); 156 | void setOffset(int offset); 157 | void setSelectedTickLabelFont(const QFont &font); 158 | void setSelectedLabelFont(const QFont &font); 159 | void setSelectedTickLabelColor(const QColor &color); 160 | void setSelectedLabelColor(const QColor &color); 161 | void setSelectedBasePen(const QPen &pen); 162 | void setSelectedTickPen(const QPen &pen); 163 | void setSelectedSubTickPen(const QPen &pen); 164 | Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); 165 | Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); 166 | void setLowerEnding(const QCPLineEnding &ending); 167 | void setUpperEnding(const QCPLineEnding &ending); 168 | 169 | // reimplemented virtual methods: 170 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 171 | 172 | // non-property methods: 173 | Qt::Orientation orientation() const; 174 | int pixelOrientation() const; 175 | void moveRange(double diff); 176 | void scaleRange(double factor); 177 | void scaleRange(double factor, double center); 178 | void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); 179 | void rescale(bool onlyVisiblePlottables=false); 180 | double pixelToCoord(double value) const; 181 | double coordToPixel(double value) const; 182 | SelectablePart getPartAt(const QPointF &pos) const; 183 | QList plottables() const; 184 | QList graphs() const; 185 | QList items() const; 186 | 187 | static AxisType marginSideToAxisType(QCP::MarginSide side); 188 | static Qt::Orientation orientation(AxisType type); 189 | static AxisType opposite(AxisType type); 190 | 191 | signals: 192 | void rangeChanged(const QCPRange &newRange); 193 | void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); 194 | void scaleTypeChanged(QCPAxis::ScaleType scaleType); 195 | void selectionChanged(const QCPAxis::SelectableParts &parts); 196 | void selectableChanged(const QCPAxis::SelectableParts &parts); 197 | }; 198 | -------------------------------------------------------------------------------- /core.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCustomPlot : public QWidget 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | enum LayerInsertMode { limBelow ///< Layer is inserted below other layer 18 | ,limAbove ///< Layer is inserted above other layer 19 | }; 20 | 21 | enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot 22 | ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided. 23 | ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints. 24 | ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority. 25 | }; 26 | 27 | QCustomPlot(QWidget *parent /TransferThis/ = 0); 28 | virtual ~QCustomPlot(); 29 | 30 | // getters: 31 | QRect viewport() const; 32 | double bufferDevicePixelRatio() const; 33 | QPixmap background() const; 34 | bool backgroundScaled() const; 35 | Qt::AspectRatioMode backgroundScaledMode() const; 36 | QCPLayoutGrid *plotLayout() const; 37 | QCP::AntialiasedElements antialiasedElements() const; 38 | QCP::AntialiasedElements notAntialiasedElements() const; 39 | bool autoAddPlottableToLegend() const; 40 | const QCP::Interactions interactions() const; 41 | int selectionTolerance() const; 42 | bool noAntialiasingOnDrag() const; 43 | QCP::PlottingHints plottingHints() const; 44 | Qt::KeyboardModifier multiSelectModifier() const; 45 | QCP::SelectionRectMode selectionRectMode() const; 46 | QCPSelectionRect *selectionRect() const; 47 | bool openGl() const; 48 | bool repaintAll() const; 49 | 50 | // setters: 51 | void setViewport(const QRect &rect); 52 | void setBufferDevicePixelRatio(double ratio); 53 | void setBackground(const QPixmap &pm); 54 | void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); 55 | void setBackground(const QBrush &brush); 56 | void setBackgroundScaled(bool scaled); 57 | void setBackgroundScaledMode(Qt::AspectRatioMode mode); 58 | void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); 59 | void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); 60 | void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); 61 | void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); 62 | void setAutoAddPlottableToLegend(bool on); 63 | void setInteractions(const QCP::Interactions &interactions); 64 | void setInteraction(const QCP::Interaction &interaction, bool enabled=true); 65 | void setSelectionTolerance(int pixels); 66 | void setNoAntialiasingOnDrag(bool enabled); 67 | void setPlottingHints(const QCP::PlottingHints &hints); 68 | void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); 69 | void setMultiSelectModifier(Qt::KeyboardModifier modifier); 70 | void setSelectionRectMode(QCP::SelectionRectMode mode); 71 | void setSelectionRect(QCPSelectionRect *selectionRect); 72 | void setOpenGl(bool enabled, int multisampling=16); 73 | void setRepaintAll(bool repaint); 74 | 75 | // non-property methods: 76 | // plottable interface: 77 | QCPAbstractPlottable *plottable(int index); 78 | QCPAbstractPlottable *plottable(); 79 | bool removePlottable(QCPAbstractPlottable *plottable); 80 | bool removePlottable(int index); 81 | int clearPlottables(); 82 | int plottableCount() const; 83 | QList selectedPlottables() const; 84 | QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; 85 | bool hasPlottable(QCPAbstractPlottable *plottable) const; 86 | 87 | // specialized interface for QCPGraph: 88 | QCPGraph *graph(int index) const; 89 | QCPGraph *graph() const; 90 | QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); 91 | bool removeGraph(QCPGraph *graph); 92 | bool removeGraph(int index); 93 | int clearGraphs(); 94 | int graphCount() const; 95 | QList selectedGraphs() const; 96 | 97 | // item interface: 98 | QCPAbstractItem *item(int index) const; 99 | QCPAbstractItem *item() const; 100 | bool removeItem(QCPAbstractItem *item); 101 | bool removeItem(int index); 102 | int clearItems(); 103 | int itemCount() const; 104 | QList selectedItems() const; 105 | QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; 106 | bool hasItem(QCPAbstractItem *item) const; 107 | 108 | // layer interface: 109 | QCPLayer *layer(const QString &name) const; 110 | QCPLayer *layer(int index) const; 111 | QCPLayer *currentLayer() const; 112 | bool setCurrentLayer(const QString &name); 113 | bool setCurrentLayer(QCPLayer *layer); 114 | int layerCount() const; 115 | bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); 116 | bool removeLayer(QCPLayer *layer); 117 | bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); 118 | 119 | // axis rect/layout interface: 120 | int axisRectCount() const; 121 | QCPAxisRect* axisRect(int index=0) const; 122 | QList axisRects() const; 123 | QCPLayoutElement* layoutElementAt(const QPointF &pos) const; 124 | QCPAxisRect* axisRectAt(const QPointF &pos) const; 125 | Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); 126 | 127 | QList selectedAxes() const; 128 | QList selectedLegends() const; 129 | Q_SLOT void deselectAll(); 130 | 131 | bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); 132 | bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); 133 | bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); 134 | bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); 135 | bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch); 136 | QPixmap toPixmap(int width=0, int height=0, double scale=1.0); 137 | void toPainter(QCPPainter *painter, int width=0, int height=0); 138 | Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint); 139 | 140 | QCPAxis *xAxis; 141 | QCPAxis *yAxis; 142 | QCPAxis *xAxis2; 143 | QCPAxis *yAxis2; 144 | QCPLegend *legend; 145 | 146 | signals: 147 | void mouseDoubleClick(QMouseEvent *event); 148 | void mousePress(QMouseEvent *event); 149 | void mouseMove(QMouseEvent *event); 150 | void mouseRelease(QMouseEvent *event); 151 | void mouseWheel(QWheelEvent *event); 152 | 153 | void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); 154 | void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); 155 | void itemClick(QCPAbstractItem *item, QMouseEvent *event); 156 | void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); 157 | void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); 158 | void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); 159 | void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); 160 | void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); 161 | 162 | void selectionChangedByUser(); 163 | void beforeReplot(); 164 | void afterReplot(); 165 | }; 166 | -------------------------------------------------------------------------------- /item.sip: -------------------------------------------------------------------------------- 1 | /** PyQt5 binding for QCustomPlot v2.0.0 2 | * 3 | * Authors: Dmitry Voronin, Giuseppe Corbelli 4 | * License: MIT 5 | * 6 | * QCustomPlot author: Emanuel Eichhammer 7 | * QCustomPlot Website/Contact: http://www.qcustomplot.com 8 | */ 9 | 10 | 11 | class QCPItemAnchor /NoDefaultCtors/ 12 | { 13 | %TypeHeaderCode 14 | #include 15 | %End 16 | public: 17 | QCPItemAnchor(QCustomPlot *parentPlot /TransferThis/, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1); 18 | virtual ~QCPItemAnchor(); 19 | 20 | // getters: 21 | QString name() const; 22 | virtual QPointF pixelPosition() const; 23 | }; 24 | 25 | 26 | class QCPItemLine : public QCPAbstractItem /NoDefaultCtors/ 27 | { 28 | %TypeHeaderCode 29 | #include 30 | %End 31 | 32 | public: 33 | QCPItemLine(QCustomPlot *parentPlot /TransferThis/); 34 | virtual ~QCPItemLine(); 35 | 36 | // getters: 37 | QPen pen() const; 38 | QPen selectedPen() const; 39 | QCPLineEnding head() const; 40 | QCPLineEnding tail() const; 41 | 42 | // setters; 43 | void setPen(const QPen &pen); 44 | void setSelectedPen(const QPen &pen); 45 | void setHead(const QCPLineEnding &head); 46 | void setTail(const QCPLineEnding &tail); 47 | 48 | // reimplemented virtual methods: 49 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 50 | 51 | // There's nothing like 'const' in python 52 | QCPItemPosition *start 53 | { 54 | %GetCode 55 | return sipConvertFromType(const_cast<::QCPItemPosition*>(sipCpp->start), sipType_QCPItemPosition, NULL); 56 | %End 57 | 58 | %SetCode 59 | PyErr_SetString(PyExc_AttributeError, "'start' attribute cannot be assigned"); 60 | sipErr = 1; 61 | %End 62 | }; 63 | 64 | QCPItemPosition *end 65 | { 66 | %GetCode 67 | return sipConvertFromType(const_cast<::QCPItemPosition*>(sipCpp->end), sipType_QCPItemPosition, NULL); 68 | %End 69 | 70 | %SetCode 71 | PyErr_SetString(PyExc_AttributeError, "'end' attribute cannot be assigned"); 72 | sipErr = 1; 73 | %End 74 | }; 75 | 76 | protected: 77 | // reimplemented virtual methods: 78 | virtual void draw(QCPPainter *painter); 79 | 80 | // non-virtual methods: 81 | QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const; 82 | QPen mainPen() const; 83 | }; 84 | 85 | 86 | class QCPItemTracer : public QCPAbstractItem /NoDefaultCtors/ 87 | { 88 | %TypeHeaderCode 89 | #include 90 | %End 91 | 92 | public: 93 | enum TracerStyle { tsNone ///< The tracer is not visible 94 | ,tsPlus ///< A plus shaped crosshair with limited size 95 | ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect 96 | ,tsCircle ///< A circle 97 | ,tsSquare ///< A square 98 | }; 99 | 100 | QCPItemTracer(QCustomPlot *parentPlot /TransferThis/); 101 | virtual ~QCPItemTracer(); 102 | 103 | // getters: 104 | QPen pen() const; 105 | QPen selectedPen() const; 106 | QBrush brush() const; 107 | QBrush selectedBrush() const; 108 | double size() const; 109 | TracerStyle style() const; 110 | QCPGraph *graph() const; 111 | double graphKey() const; 112 | bool interpolating() const; 113 | 114 | // setters; 115 | void setPen(const QPen &pen); 116 | void setSelectedPen(const QPen &pen); 117 | void setBrush(const QBrush &brush); 118 | void setSelectedBrush(const QBrush &brush); 119 | void setSize(double size); 120 | void setStyle(TracerStyle style); 121 | void setGraph(QCPGraph *graph); 122 | void setGraphKey(double key); 123 | void setInterpolating(bool enabled); 124 | 125 | // reimplemented virtual methods: 126 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; 127 | 128 | // non-virtual methods: 129 | void updatePosition(); 130 | 131 | // There's nothing like 'const' in python 132 | QCPItemPosition *position 133 | { 134 | %GetCode 135 | return sipConvertFromType(const_cast<::QCPItemPosition*>(sipCpp->position), sipType_QCPItemPosition, NULL); 136 | %End 137 | 138 | %SetCode 139 | PyErr_SetString(PyExc_AttributeError, "'position' attribute cannot be assigned"); 140 | sipErr = 1; 141 | %End 142 | }; 143 | 144 | protected: 145 | // reimplemented virtual methods: 146 | virtual void draw(QCPPainter *painter); 147 | 148 | // non-virtual methods: 149 | QPen mainPen() const; 150 | QBrush mainBrush() const; 151 | }; 152 | 153 | 154 | class QCPItemPosition : public QCPItemAnchor /NoDefaultCtors/ 155 | { 156 | %TypeHeaderCode 157 | #include 158 | %End 159 | public: 160 | enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. 161 | ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top 162 | ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and 163 | ///< vertically at the top of the viewport/widget, etc. 164 | ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top 165 | ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and 166 | ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. 167 | ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). 168 | }; 169 | 170 | QCPItemPosition(QCustomPlot *parentPlot /TransferThis/, QCPAbstractItem *parentItem, const QString &name); 171 | virtual ~QCPItemPosition(); 172 | 173 | // getters: 174 | PositionType type() const; 175 | PositionType typeX() const; 176 | PositionType typeY() const; 177 | QCPItemAnchor *parentAnchor() const; 178 | QCPItemAnchor *parentAnchorX() const; 179 | QCPItemAnchor *parentAnchorY() const; 180 | double key() const; 181 | double value() const; 182 | QPointF coords() const; 183 | QCPAxis *keyAxis() const; 184 | QCPAxis *valueAxis() const; 185 | QCPAxisRect *axisRect() const; 186 | virtual QPointF pixelPosition() const; 187 | 188 | // setters: 189 | void setType(PositionType type); 190 | void setTypeX(PositionType type); 191 | void setTypeY(PositionType type); 192 | bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); 193 | bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); 194 | bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); 195 | void setCoords(double key, double value); 196 | void setCoords(const QPointF &coords); 197 | void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); 198 | void setAxisRect(QCPAxisRect *axisRect); 199 | void setPixelPosition(const QPointF &pixelPosition); 200 | }; 201 | 202 | 203 | class QCPAbstractItem : public QCPLayerable /Abstract/ 204 | { 205 | %TypeHeaderCode 206 | #include 207 | %End 208 | public: 209 | explicit QCPAbstractItem(QCustomPlot *parentPlot /TransferThis/); 210 | virtual ~QCPAbstractItem(); 211 | 212 | // getters: 213 | bool clipToAxisRect() const; 214 | QCPAxisRect *clipAxisRect() const; 215 | bool selectable() const; 216 | bool selected() const; 217 | 218 | // setters: 219 | void setClipToAxisRect(bool clip); 220 | void setClipAxisRect(QCPAxisRect *rect); 221 | Q_SLOT void setSelectable(bool selectable); 222 | Q_SLOT void setSelected(bool selected); 223 | 224 | // reimplemented virtual methods: 225 | virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; 226 | 227 | // non-virtual methods: 228 | QList positions() const; 229 | QList anchors() const; 230 | QCPItemPosition *position(const QString &name) const; 231 | QCPItemAnchor *anchor(const QString &name) const; 232 | bool hasAnchor(const QString &name) const; 233 | 234 | signals: 235 | void selectionChanged(bool selected); 236 | void selectableChanged(bool selectable); 237 | }; 238 | -------------------------------------------------------------------------------- /examples/plots/mainwindow.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # PyQt5 binding for QCustomPlot v2.0.0 5 | # 6 | # Authors: Dmitry Voronin, Giuseppe Corbelli 7 | # License: MIT 8 | # 9 | # QCustomPlot author: Emanuel Eichhammer 10 | # QCustomPlot Website/Contact: http://www.qcustomplot.com 11 | 12 | import math 13 | 14 | from PyQt5.QtCore import QTimer, QPointF, Qt 15 | from PyQt5.QtGui import QPen, QBrush, QColor, QRadialGradient, QLinearGradient 16 | from PyQt5.QtWidgets import QMainWindow 17 | from PyQt5.uic import loadUi 18 | 19 | import QCustomPlot 20 | 21 | from QCustomPlot import QCP 22 | 23 | class MainWindow(QMainWindow): 24 | def __init__(self, argv, parent=None): 25 | super().__init__(parent) 26 | loadUi("mainwindow.ui", self) 27 | 28 | self._available_demos = { 29 | 0: self.setupQuadraticDemo, 30 | 1: self.setupSimpleDemo, 31 | # 2: self.setupSincScatterDemo, 32 | # 3: self.setupScatterStyleDemo, 33 | # 4: self.setupScatterPixmapDemo, 34 | # 5: self.setupLineStyleDemo, 35 | # 6: self.setupDateDemo, 36 | # 7: self.setupTextureBrushDemo, 37 | # 8: self.setupMultiAxisDemo, 38 | # 9: self.setupLogarithmicDemo, 39 | # 10: self.setupRealtimeDataDemo, 40 | 11: self.setupParametricCurveDemo, 41 | 12: self.setupBarChartDemo, 42 | # 13: self.setupStatisticalDemo, 43 | # 14: self.setupSimpleItemDemo, 44 | # 15: self.setupItemDemo, 45 | # 16: self.setupStyledDemo, 46 | # 17: self.setupAdvancedAxesDemo, 47 | # 18: self.setupColorMapDemo, 48 | # 19: self.setupFinancialDemo, 49 | } 50 | 51 | self.currentDemoIndex = -1 52 | self.demoName = "" 53 | self.setGeometry(400, 250, 542, 390) 54 | try: 55 | demoIndex = int(argv[-1]) 56 | self._available_demos[demoIndex] 57 | except Exception: 58 | demoIndex = 0 59 | 60 | self.setupDemo(demoIndex) 61 | 62 | def setupDemo(self, demoIndex): 63 | self._available_demos[demoIndex]() 64 | self.setWindowTitle("QCustomPlot demo: {}".format(self.demoName)) 65 | self.statusBar.clearMessage() 66 | self.currentDemoIndex = demoIndex 67 | self.customPlot.replot() 68 | 69 | def setupQuadraticDemo(self): 70 | self.demoName = "Quadratic Demo" 71 | # generate some data: initialize with entries 0..100 72 | x = [0] * 100 73 | y = [0] * 100 74 | for i in range(0, 100): 75 | x[i] = i/50.0 - 1 # x goes from -1 to 1 76 | y[i] = x[i]*x[i] # let's plot a quadratic function 77 | 78 | # create graph and assign data to it: 79 | self.customPlot.addGraph() 80 | self.customPlot.graph(0).setData(x, y) 81 | # give the axes some labels: 82 | self.customPlot.xAxis.setLabel("x") 83 | self.customPlot.yAxis.setLabel("y") 84 | # set axes ranges, so we see all data: 85 | self.customPlot.xAxis.setRange(-1, 1) 86 | self.customPlot.yAxis.setRange(0, 1) 87 | 88 | def setupSimpleDemo(self): 89 | self.demoName = "Simple Demo" 90 | 91 | # add two new graphs and set their look: 92 | self.customPlot.addGraph() 93 | self.customPlot.graph(0).setPen(QPen(QColor("blue"))) # line color blue for first graph 94 | self.customPlot.graph(0).setBrush(QBrush(QColor(0, 0, 255, 20))) # first graph will be filled with translucent blue 95 | self.customPlot.addGraph(); 96 | self.customPlot.graph(1).setPen(QPen(QColor("red"))) # line color red for second graph 97 | # generate some points of data (y0 for first, y1 for second graph): 98 | x = [0.0] * 251 99 | y0 = [0.0] * 251 100 | y1 = [0.0] * 251 101 | for i in range(0, 251): 102 | x[i] = float(i) 103 | y0[i] = pow(math.e, -i/150.0) * math.cos(i/10.0) # exponentially decaying cosine 104 | y1[i] = pow(math.e, -i/150.0) # exponential envelope 105 | 106 | # configure right and top axis to show ticks but no labels: 107 | # (see QCPAxisRect::setupFullAxesBox for a quicker method to do this) 108 | self.customPlot.xAxis2.setVisible(True) 109 | self.customPlot.xAxis2.setTickLabels(False) 110 | self.customPlot.yAxis2.setVisible(True) 111 | self.customPlot.yAxis2.setTickLabels(False) 112 | # make left and bottom axes always transfer their ranges to right and top axes: 113 | self.customPlot.xAxis.rangeChanged.connect(self.customPlot.xAxis2.setRange) 114 | self.customPlot.yAxis.rangeChanged.connect(self.customPlot.yAxis2.setRange) 115 | # pass data points to graphs: 116 | self.customPlot.graph(0).setData(x, y0) 117 | self.customPlot.graph(1).setData(x, y1) 118 | # let the ranges scale themselves so graph 0 fits perfectly in the visible area: 119 | self.customPlot.graph(0).rescaleAxes() 120 | # same thing for graph 1, but only enlarge ranges (in case graph 1 is smaller than graph 0): 121 | self.customPlot.graph(1).rescaleAxes(True) 122 | # Note: we could have also just called customPlot->rescaleAxes(); instead 123 | # Allow user to drag axis ranges with mouse, zoom with mouse wheel and select graphs by clicking: 124 | # TODO: figure out how to skip the explicit intermediate QCP.Interactions 125 | self.customPlot.setInteractions(QCustomPlot.QCP.Interactions(QCP.iRangeDrag | QCP.iRangeZoom | QCP.iSelectPlottables)) 126 | 127 | # void setupSincScatterDemo(QCustomPlot *customPlot); 128 | # void setupScatterStyleDemo(QCustomPlot *customPlot); 129 | # void setupLineStyleDemo(QCustomPlot *customPlot); 130 | # void setupScatterPixmapDemo(QCustomPlot *customPlot); 131 | # void setupDateDemo(QCustomPlot *customPlot); 132 | # void setupTextureBrushDemo(QCustomPlot *customPlot); 133 | # void setupMultiAxisDemo(QCustomPlot *customPlot); 134 | # void setupLogarithmicDemo(QCustomPlot *customPlot); 135 | # void setupRealtimeDataDemo(QCustomPlot *customPlot); 136 | 137 | def setupParametricCurveDemo(self): 138 | self.demoName = "Parametric Curves Demo" 139 | 140 | # create empty curve objects. As they are not adopted by main QCustomPlot an explicit 141 | # reference must be kept 142 | self.fermatSpiral1 = QCustomPlot.QCPCurve(self.customPlot.xAxis, self.customPlot.yAxis) 143 | self.fermatSpiral2 = QCustomPlot.QCPCurve(self.customPlot.xAxis, self.customPlot.yAxis) 144 | self.deltoidRadial = QCustomPlot.QCPCurve(self.customPlot.xAxis, self.customPlot.yAxis) 145 | # generate the curve data points: 146 | pointCount = 501 147 | dataSpiral1 = [[0.0] * pointCount, [0.0] * pointCount, [0.0] * pointCount] 148 | dataSpiral2 = [[0.0] * pointCount, [0.0] * pointCount, [0.0] * pointCount] 149 | dataDeltoid = [[0.0] * pointCount, [0.0] * pointCount, [0.0] * pointCount] 150 | for i in range(0, pointCount): 151 | phi = i/(pointCount-1) * 8 * math.pi 152 | theta = i/(pointCount-1) * 2 * math.pi 153 | dataSpiral1[0][i] = float(i) 154 | dataSpiral1[1][i] = math.sqrt(phi) * math.cos(phi) 155 | dataSpiral1[2][i] = math.sqrt(phi) * math.sin(phi) 156 | dataSpiral2[0][i] = float(i) 157 | dataSpiral2[1][i] = -dataSpiral1[1][i] 158 | dataSpiral2[2][i] = -dataSpiral1[2][i] 159 | dataDeltoid[0][i] = float(i) 160 | dataDeltoid[1][i] = 2 * math.cos(2*theta) + math.cos(1*theta) + 2 * math.sin(theta) 161 | dataDeltoid[2][i] = 2 * math.sin(2*theta) - math.sin(1*theta) 162 | 163 | # pass the data to the curves; we know t (i in loop above) is ascending, so set alreadySorted=true (saves an extra internal sort): 164 | self.fermatSpiral1.setData(dataSpiral1[0], dataSpiral1[1], dataSpiral1[2], True) 165 | self.fermatSpiral2.setData(dataSpiral2[0], dataSpiral2[1], dataSpiral2[2], True) 166 | self.deltoidRadial.setData(dataDeltoid[0], dataDeltoid[1], dataDeltoid[2], True) 167 | # color the curves: 168 | self.fermatSpiral1.setPen(QPen(Qt.blue)) 169 | self.fermatSpiral1.setBrush(QBrush(QColor(0, 0, 255, 20))) 170 | self.fermatSpiral2.setPen(QPen(QColor(255, 120, 0))) 171 | self.fermatSpiral2.setBrush(QBrush(QColor(255, 120, 0, 30))) 172 | radialGrad = QRadialGradient(QPointF(310, 180), 200) 173 | radialGrad.setColorAt(0, QColor(170, 20, 240, 100)) 174 | radialGrad.setColorAt(0.5, QColor(20, 10, 255, 40)) 175 | radialGrad.setColorAt(1, QColor(120, 20, 240, 10)) 176 | self.deltoidRadial.setPen(QPen(QColor(170, 20, 240))) 177 | self.deltoidRadial.setBrush(QBrush(radialGrad)) 178 | # set some basic customPlot config: 179 | self.customPlot.setInteractions(QCustomPlot.QCP.Interactions(QCustomPlot.QCP.iRangeDrag | QCustomPlot.QCP.iRangeZoom | QCustomPlot.QCP.iSelectPlottables)) 180 | self.customPlot.axisRect().setupFullAxesBox() 181 | self.customPlot.rescaleAxes() 182 | #~ def setupParametricCurveDemo(self): 183 | 184 | def setupBarChartDemo(self): 185 | self.demoName = "Bar Chart Demo" 186 | 187 | # set dark background gradient: 188 | gradient = QLinearGradient(0, 0, 0, 400) 189 | gradient.setColorAt(0, QColor(90, 90, 90)) 190 | gradient.setColorAt(0.38, QColor(105, 105, 105)) 191 | gradient.setColorAt(1, QColor(70, 70, 70)) 192 | self.customPlot.setBackground(QBrush(gradient)) 193 | 194 | # create empty bar chart objects: 195 | regen = QCustomPlot.QCPBars(self.customPlot.xAxis, self.customPlot.yAxis) 196 | nuclear = QCustomPlot.QCPBars(self.customPlot.xAxis, self.customPlot.yAxis) 197 | fossil = QCustomPlot.QCPBars(self.customPlot.xAxis, self.customPlot.yAxis) 198 | 199 | regen.setAntialiased(False) # gives more crisp, pixel aligned bar borders 200 | nuclear.setAntialiased(False) 201 | fossil.setAntialiased(False) 202 | regen.setStackingGap(1) 203 | nuclear.setStackingGap(1) 204 | fossil.setStackingGap(1) 205 | # set names and colors: 206 | fossil.setName("Fossil fuels") 207 | fossil.setPen(QPen(QColor(111, 9, 176).lighter(170))) 208 | fossil.setBrush(QColor(111, 9, 176)) 209 | nuclear.setName("Nuclear") 210 | nuclear.setPen(QPen(QColor(250, 170, 20).lighter(150))) 211 | nuclear.setBrush(QColor(250, 170, 20)) 212 | regen.setName("Regenerative") 213 | regen.setPen(QPen(QColor(0, 168, 140).lighter(130))) 214 | regen.setBrush(QColor(0, 168, 140)) 215 | # stack bars on top of each other: 216 | nuclear.moveAbove(fossil) 217 | regen.moveAbove(nuclear) 218 | 219 | # prepare x axis with country labels: 220 | ticks = [float(i) for i in range(1, 8)] 221 | labels = ["USA", "Japan", "Germany", "France", "UK", "Italy", "Canada"] 222 | textTicker = QCustomPlot.QCPAxisTickerText() 223 | textTicker.addTicks(ticks, labels) 224 | self.customPlot.xAxis.setTicker(textTicker) 225 | self.customPlot.xAxis.setTickLabelRotation(60) 226 | self.customPlot.xAxis.setSubTicks(False) 227 | self.customPlot.xAxis.setTickLength(0, 4) 228 | self.customPlot.xAxis.setRange(0, 8) 229 | self.customPlot.xAxis.setBasePen(QPen(Qt.white)) 230 | self.customPlot.xAxis.setTickPen(QPen(Qt.white)) 231 | self.customPlot.xAxis.grid().setVisible(True) 232 | self.customPlot.xAxis.grid().setPen(QPen(QColor(130, 130, 130), 0, Qt.DotLine)) 233 | self.customPlot.xAxis.setTickLabelColor(Qt.white) 234 | self.customPlot.xAxis.setLabelColor(Qt.white) 235 | 236 | # prepare y axis: 237 | self.customPlot.yAxis.setRange(0, 12.1) 238 | self.customPlot.yAxis.setPadding(5) # a bit more space to the left border 239 | self.customPlot.yAxis.setLabel("Power Consumption in\nKilowatts per Capita (2007)") 240 | self.customPlot.yAxis.setBasePen(QPen(Qt.white)) 241 | self.customPlot.yAxis.setTickPen(QPen(Qt.white)) 242 | self.customPlot.yAxis.setSubTickPen(QPen(Qt.white)) 243 | self.customPlot.yAxis.grid().setSubGridVisible(True) 244 | self.customPlot.yAxis.setTickLabelColor(Qt.white) 245 | self.customPlot.yAxis.setLabelColor(Qt.white) 246 | self.customPlot.yAxis.grid().setPen(QPen(QColor(130, 130, 130), 0, Qt.SolidLine)) 247 | self.customPlot.yAxis.grid().setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt.DotLine)) 248 | 249 | # Add data: 250 | fossilData = [0.86*10.5, 0.83*5.5, 0.84*5.5, 0.52*5.8, 0.89*5.2, 0.90*4.2, 0.67*11.2] 251 | nuclearData = [0.08*10.5, 0.12*5.5, 0.12*5.5, 0.40*5.8, 0.09*5.2, 0.00*4.2, 0.07*11.2] 252 | regenData = [0.06*10.5, 0.05*5.5, 0.04*5.5, 0.06*5.8, 0.02*5.2, 0.07*4.2, 0.25*11.2] 253 | fossil.setData(ticks, fossilData) 254 | nuclear.setData(ticks, nuclearData) 255 | regen.setData(ticks, regenData) 256 | 257 | # setup legend: 258 | self.customPlot.legend.setVisible(True) 259 | self.customPlot.axisRect().insetLayout().setInsetAlignment(0, Qt.AlignTop|Qt.AlignHCenter) 260 | self.customPlot.legend.setBrush(QColor(255, 255, 255, 100)) 261 | self.customPlot.legend.setBorderPen(QPen(Qt.NoPen)) 262 | legendFont = self.font() 263 | legendFont.setPointSize(10) 264 | self.customPlot.legend.setFont(legendFont) 265 | self.customPlot.setInteractions(QCustomPlot.QCP.Interactions(QCP.iRangeDrag | QCP.iRangeZoom)) 266 | #~ def setupBarChartDemo(self): 267 | 268 | # void setupStatisticalDemo(QCustomPlot *customPlot); 269 | # void setupSimpleItemDemo(QCustomPlot *customPlot); 270 | # void setupItemDemo(QCustomPlot *customPlot); 271 | # void setupStyledDemo(QCustomPlot *customPlot); 272 | # void setupAdvancedAxesDemo(QCustomPlot *customPlot); 273 | # void setupColorMapDemo(QCustomPlot *customPlot); 274 | # void setupFinancialDemo(QCustomPlot *customPlot); 275 | # 276 | # void setupPlayground(QCustomPlot *customPlot); 277 | --------------------------------------------------------------------------------