PythonQwt 0.14.6__tar.gz → 0.15.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pythonqwt-0.14.6/PythonQwt.egg-info → pythonqwt-0.15.0}/PKG-INFO +3 -3
- {pythonqwt-0.14.6 → pythonqwt-0.15.0/PythonQwt.egg-info}/PKG-INFO +3 -3
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/README.md +2 -2
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/plot_example.py +2 -2
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/__init__.py +11 -3
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot.py +3 -3
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/scale_draw.py +60 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/scale_engine.py +172 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/conftest.py +22 -8
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_cpudemo.py +1 -1
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/text.py +7 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/LICENSE +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/MANIFEST.in +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/PythonQwt-tests.desktop +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/PythonQwt.egg-info/SOURCES.txt +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/PythonQwt.egg-info/dependency_links.txt +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/PythonQwt.egg-info/entry_points.txt +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/PythonQwt.egg-info/requires.txt +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/PythonQwt.egg-info/top_level.txt +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/_static/PythonQwt_logo.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/_static/QwtPlot_example.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/_static/panorama.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/_static/symbol_path_example.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/conf.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/bodedemo.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/cartesian.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/cpudemo.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/curvebenchmark1.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/curvebenchmark2.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/curvedemo1.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/curvedemo2.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/data.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/errorbar.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/eventfilter.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/image.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/index.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/logcurve.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/mapdemo.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/multidemo.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/simple.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/examples/vertical.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/index.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/installation.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/overview.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/graphic.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/index.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/interval.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/plot.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/plot_directpainter.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/plot_layout.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/plot_series.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/scale.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/symbol.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/text.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/toqimage.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/reference/transform.rst +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/requirements.txt +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/doc/symbol_path_example.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/pyproject.toml +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/_math.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/color_map.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/column_symbol.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/dyngrid_layout.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/graphic.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/interval.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/legend.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/null_paintdevice.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/painter.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/painter_command.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot_canvas.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot_curve.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot_directpainter.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot_grid.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot_layout.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot_marker.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot_renderer.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/plot_series.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/qthelpers.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/scale_div.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/scale_map.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/scale_widget.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/symbol.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/__init__.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/comparative_benchmarks.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/PythonQwt.svg +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/bodedemo.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/cartesian.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/cpudemo.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/curvebenchmark1.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/curvebenchmark2.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/curvedemo1.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/curvedemo2.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/data.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/errorbar.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/eventfilter.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/image.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/loadtest.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/logcurve.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/mapdemo.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/multidemo.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/simple.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/stylesheet.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/symbol.svg +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/symbols.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/testlauncher.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/data/vertical.png +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_backingstore.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_bodedemo.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_cartesian.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_curvebenchmark1.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_curvebenchmark2.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_curvedemo1.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_curvedemo2.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_data.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_errorbar.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_eventfilter.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_highdpi.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_image.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_loadtest.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_logcurve.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_mapdemo.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_multidemo.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_relativemargin.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_simple.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_stylesheet.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_symbols.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/test_vertical.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/tests/utils.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/toqimage.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/qwt/transform.py +0 -0
- {pythonqwt-0.14.6 → pythonqwt-0.15.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PythonQwt
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: Qt plotting widgets for Python
|
|
5
5
|
Author-email: Pierre Raybaut <pierre.raybaut@gmail.com>
|
|
6
6
|
License: PythonQwt License Agreement
|
|
@@ -736,8 +736,8 @@ plot.insertLegend(qwt.QwtLegend(), qwt.QwtPlot.BottomLegend)
|
|
|
736
736
|
|
|
737
737
|
# Create two curves and attach them to plot
|
|
738
738
|
x = np.linspace(-10, 10, 500)
|
|
739
|
-
qwt.QwtPlotCurve.make(x, np.cos(x), "
|
|
740
|
-
qwt.QwtPlotCurve.make(x, np.sin(x), "
|
|
739
|
+
qwt.QwtPlotCurve.make(x, np.cos(x), "Cosine", plot, linecolor="red", antialiased=True)
|
|
740
|
+
qwt.QwtPlotCurve.make(x, np.sin(x), "Sine", plot, linecolor="blue", antialiased=True)
|
|
741
741
|
|
|
742
742
|
# Resize and show plot
|
|
743
743
|
plot.resize(600, 300)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PythonQwt
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: Qt plotting widgets for Python
|
|
5
5
|
Author-email: Pierre Raybaut <pierre.raybaut@gmail.com>
|
|
6
6
|
License: PythonQwt License Agreement
|
|
@@ -736,8 +736,8 @@ plot.insertLegend(qwt.QwtLegend(), qwt.QwtPlot.BottomLegend)
|
|
|
736
736
|
|
|
737
737
|
# Create two curves and attach them to plot
|
|
738
738
|
x = np.linspace(-10, 10, 500)
|
|
739
|
-
qwt.QwtPlotCurve.make(x, np.cos(x), "
|
|
740
|
-
qwt.QwtPlotCurve.make(x, np.sin(x), "
|
|
739
|
+
qwt.QwtPlotCurve.make(x, np.cos(x), "Cosine", plot, linecolor="red", antialiased=True)
|
|
740
|
+
qwt.QwtPlotCurve.make(x, np.sin(x), "Sine", plot, linecolor="blue", antialiased=True)
|
|
741
741
|
|
|
742
742
|
# Resize and show plot
|
|
743
743
|
plot.resize(600, 300)
|
|
@@ -33,8 +33,8 @@ plot.insertLegend(qwt.QwtLegend(), qwt.QwtPlot.BottomLegend)
|
|
|
33
33
|
|
|
34
34
|
# Create two curves and attach them to plot
|
|
35
35
|
x = np.linspace(-10, 10, 500)
|
|
36
|
-
qwt.QwtPlotCurve.make(x, np.cos(x), "
|
|
37
|
-
qwt.QwtPlotCurve.make(x, np.sin(x), "
|
|
36
|
+
qwt.QwtPlotCurve.make(x, np.cos(x), "Cosine", plot, linecolor="red", antialiased=True)
|
|
37
|
+
qwt.QwtPlotCurve.make(x, np.sin(x), "Sine", plot, linecolor="blue", antialiased=True)
|
|
38
38
|
|
|
39
39
|
# Resize and show plot
|
|
40
40
|
plot.resize(600, 300)
|
|
@@ -10,8 +10,8 @@ app = QW.QApplication([])
|
|
|
10
10
|
x = np.linspace(-10, 10, 500)
|
|
11
11
|
plot = qwt.QwtPlot("Trigonometric functions")
|
|
12
12
|
plot.insertLegend(qwt.QwtLegend(), qwt.QwtPlot.BottomLegend)
|
|
13
|
-
qwt.QwtPlotCurve.make(x, np.cos(x), "
|
|
14
|
-
qwt.QwtPlotCurve.make(x, np.sin(x), "
|
|
13
|
+
qwt.QwtPlotCurve.make(x, np.cos(x), "Cosine", plot, linecolor="red", antialiased=True)
|
|
14
|
+
qwt.QwtPlotCurve.make(x, np.sin(x), "Sine", plot, linecolor="blue", antialiased=True)
|
|
15
15
|
qth.take_screenshot(
|
|
16
16
|
plot,
|
|
17
17
|
osp.join(osp.abspath(osp.dirname(__file__)), "_static", "QwtPlot_example.png"),
|
|
@@ -48,14 +48,22 @@ from qwt.plot_series import ( # noqa: F401
|
|
|
48
48
|
QwtSeriesStore,
|
|
49
49
|
)
|
|
50
50
|
from qwt.scale_div import QwtScaleDiv # noqa: F401
|
|
51
|
-
from qwt.scale_draw import
|
|
52
|
-
|
|
51
|
+
from qwt.scale_draw import ( # noqa: F401
|
|
52
|
+
QwtAbstractScaleDraw,
|
|
53
|
+
QwtDateTimeScaleDraw,
|
|
54
|
+
QwtScaleDraw,
|
|
55
|
+
)
|
|
56
|
+
from qwt.scale_engine import ( # noqa: F401
|
|
57
|
+
QwtDateTimeScaleEngine,
|
|
58
|
+
QwtLinearScaleEngine,
|
|
59
|
+
QwtLogScaleEngine,
|
|
60
|
+
)
|
|
53
61
|
from qwt.scale_map import QwtScaleMap # noqa: F401
|
|
54
62
|
from qwt.symbol import QwtSymbol as QSbl # see deprecated section
|
|
55
63
|
from qwt.text import QwtText # noqa: F401
|
|
56
64
|
from qwt.toqimage import array_to_qimage as toQImage # noqa: F401
|
|
57
65
|
|
|
58
|
-
__version__ = "0.
|
|
66
|
+
__version__ = "0.15.0"
|
|
59
67
|
QWT_VERSION_STR = "6.1.5"
|
|
60
68
|
|
|
61
69
|
|
|
@@ -132,8 +132,8 @@ class QwtPlot(QFrame):
|
|
|
132
132
|
x = np.linspace(-10, 10, 500)
|
|
133
133
|
plot = qwt.QwtPlot("Trigonometric functions")
|
|
134
134
|
plot.insertLegend(qwt.QwtLegend(), qwt.QwtPlot.BottomLegend)
|
|
135
|
-
qwt.QwtPlotCurve.make(x, np.cos(x), "
|
|
136
|
-
qwt.QwtPlotCurve.make(x, np.sin(x), "
|
|
135
|
+
qwt.QwtPlotCurve.make(x, np.cos(x), "Cosine", plot, linecolor="red", antialiased=True)
|
|
136
|
+
qwt.QwtPlotCurve.make(x, np.sin(x), "Sine", plot, linecolor="blue", antialiased=True)
|
|
137
137
|
plot.resize(600, 300)
|
|
138
138
|
plot.show()
|
|
139
139
|
|
|
@@ -2137,7 +2137,7 @@ class QwtPlotItem(object):
|
|
|
2137
2137
|
import warnings
|
|
2138
2138
|
|
|
2139
2139
|
warnings.warn(
|
|
2140
|
-
"`setAxis` has been removed in Qwt6:
|
|
2140
|
+
"`setAxis` has been removed in Qwt6: please use `setAxes` instead",
|
|
2141
2141
|
RuntimeWarning,
|
|
2142
2142
|
)
|
|
2143
2143
|
self.setAxes(xAxis, yAxis)
|
|
@@ -20,6 +20,7 @@ QwtScaleDraw
|
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
22
|
import math
|
|
23
|
+
from datetime import datetime
|
|
23
24
|
|
|
24
25
|
from qtpy.QtCore import (
|
|
25
26
|
QLineF,
|
|
@@ -1218,3 +1219,62 @@ class QwtScaleDraw(QwtAbstractScaleDraw):
|
|
|
1218
1219
|
sm.setPaintInterval(pos.y() + len_, pos.y())
|
|
1219
1220
|
else:
|
|
1220
1221
|
sm.setPaintInterval(pos.x(), pos.x() + len_)
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
class QwtDateTimeScaleDraw(QwtScaleDraw):
|
|
1225
|
+
"""Scale draw for datetime axis
|
|
1226
|
+
|
|
1227
|
+
This class formats axis labels as date/time strings from Unix timestamps.
|
|
1228
|
+
|
|
1229
|
+
Args:
|
|
1230
|
+
format: Format string for datetime display (default: "%Y-%m-%d %H:%M:%S").
|
|
1231
|
+
Uses Python datetime.strftime() format codes.
|
|
1232
|
+
spacing: Spacing between labels (default: 4)
|
|
1233
|
+
|
|
1234
|
+
Examples:
|
|
1235
|
+
>>> # Create a datetime scale with default format
|
|
1236
|
+
>>> scale = QwtDateTimeScaleDraw()
|
|
1237
|
+
|
|
1238
|
+
>>> # Create a datetime scale with custom format (time only)
|
|
1239
|
+
>>> scale = QwtDateTimeScaleDraw(format="%H:%M:%S")
|
|
1240
|
+
|
|
1241
|
+
>>> # Create a datetime scale with date only
|
|
1242
|
+
>>> scale = QwtDateTimeScaleDraw(format="%Y-%m-%d", spacing=4)
|
|
1243
|
+
"""
|
|
1244
|
+
|
|
1245
|
+
def __init__(self, format: str = "%Y-%m-%d %H:%M:%S", spacing: int = 4) -> None:
|
|
1246
|
+
super().__init__()
|
|
1247
|
+
self._format = format
|
|
1248
|
+
self.setSpacing(spacing)
|
|
1249
|
+
|
|
1250
|
+
def get_format(self) -> str:
|
|
1251
|
+
"""Get the current datetime format string
|
|
1252
|
+
|
|
1253
|
+
Returns:
|
|
1254
|
+
str: Format string
|
|
1255
|
+
"""
|
|
1256
|
+
return self._format
|
|
1257
|
+
|
|
1258
|
+
def set_format(self, format: str) -> None:
|
|
1259
|
+
"""Set the datetime format string
|
|
1260
|
+
|
|
1261
|
+
Args:
|
|
1262
|
+
format: Format string for datetime display
|
|
1263
|
+
"""
|
|
1264
|
+
self._format = format
|
|
1265
|
+
|
|
1266
|
+
def label(self, value: float) -> QwtText:
|
|
1267
|
+
"""Convert a timestamp value to a formatted date/time label
|
|
1268
|
+
|
|
1269
|
+
Args:
|
|
1270
|
+
value: Unix timestamp (seconds since epoch)
|
|
1271
|
+
|
|
1272
|
+
Returns:
|
|
1273
|
+
QwtText: Formatted label
|
|
1274
|
+
"""
|
|
1275
|
+
try:
|
|
1276
|
+
dt = datetime.fromtimestamp(value)
|
|
1277
|
+
return QwtText(dt.strftime(self._format))
|
|
1278
|
+
except (ValueError, OSError):
|
|
1279
|
+
# Handle invalid timestamps
|
|
1280
|
+
return QwtText("")
|
|
@@ -906,3 +906,175 @@ class QwtLogScaleEngine(QwtScaleEngine):
|
|
|
906
906
|
x2 = interval.maxValue()
|
|
907
907
|
|
|
908
908
|
return qwtPowInterval(self.base(), QwtInterval(x1, x2))
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
class QwtDateTimeScaleEngine(QwtLinearScaleEngine):
|
|
912
|
+
"""
|
|
913
|
+
A scale engine for datetime scales that creates intelligent time-based tick intervals.
|
|
914
|
+
|
|
915
|
+
This engine calculates tick intervals that correspond to meaningful time units
|
|
916
|
+
(seconds, minutes, hours, days, weeks, months, years) rather than arbitrary
|
|
917
|
+
numerical spacing.
|
|
918
|
+
"""
|
|
919
|
+
|
|
920
|
+
# Time intervals in seconds
|
|
921
|
+
TIME_INTERVALS = [
|
|
922
|
+
1, # 1 second
|
|
923
|
+
5, # 5 seconds
|
|
924
|
+
10, # 10 seconds
|
|
925
|
+
15, # 15 seconds
|
|
926
|
+
30, # 30 seconds
|
|
927
|
+
60, # 1 minute
|
|
928
|
+
2 * 60, # 2 minutes
|
|
929
|
+
5 * 60, # 5 minutes
|
|
930
|
+
10 * 60, # 10 minutes
|
|
931
|
+
15 * 60, # 15 minutes
|
|
932
|
+
30 * 60, # 30 minutes
|
|
933
|
+
60 * 60, # 1 hour
|
|
934
|
+
2 * 60 * 60, # 2 hours
|
|
935
|
+
3 * 60 * 60, # 3 hours
|
|
936
|
+
6 * 60 * 60, # 6 hours
|
|
937
|
+
12 * 60 * 60, # 12 hours
|
|
938
|
+
24 * 60 * 60, # 1 day
|
|
939
|
+
2 * 24 * 60 * 60, # 2 days
|
|
940
|
+
7 * 24 * 60 * 60, # 1 week
|
|
941
|
+
2 * 7 * 24 * 60 * 60, # 2 weeks
|
|
942
|
+
30 * 24 * 60 * 60, # 1 month (approx)
|
|
943
|
+
3 * 30 * 24 * 60 * 60, # 3 months (approx)
|
|
944
|
+
6 * 30 * 24 * 60 * 60, # 6 months (approx)
|
|
945
|
+
365 * 24 * 60 * 60, # 1 year (approx)
|
|
946
|
+
]
|
|
947
|
+
|
|
948
|
+
def __init__(self, base=10):
|
|
949
|
+
super(QwtDateTimeScaleEngine, self).__init__(base)
|
|
950
|
+
|
|
951
|
+
def divideScale(self, x1, x2, maxMajorSteps, maxMinorSteps, stepSize=0.0):
|
|
952
|
+
"""
|
|
953
|
+
Calculate a scale division for a datetime interval
|
|
954
|
+
|
|
955
|
+
:param float x1: First interval limit (Unix timestamp)
|
|
956
|
+
:param float x2: Second interval limit (Unix timestamp)
|
|
957
|
+
:param int maxMajorSteps: Maximum for the number of major steps
|
|
958
|
+
:param int maxMinorSteps: Maximum number of minor steps
|
|
959
|
+
:param float stepSize: Step size. If stepSize == 0.0, calculates intelligent datetime step
|
|
960
|
+
:return: Calculated scale division
|
|
961
|
+
"""
|
|
962
|
+
interval = QwtInterval(x1, x2).normalized()
|
|
963
|
+
if interval.width() <= 0:
|
|
964
|
+
return QwtScaleDiv()
|
|
965
|
+
|
|
966
|
+
# If stepSize is provided and > 0, use parent implementation
|
|
967
|
+
if stepSize > 0.0:
|
|
968
|
+
return super(QwtDateTimeScaleEngine, self).divideScale(
|
|
969
|
+
x1, x2, maxMajorSteps, maxMinorSteps, stepSize
|
|
970
|
+
)
|
|
971
|
+
|
|
972
|
+
# Calculate intelligent datetime step size
|
|
973
|
+
duration = interval.width() # Duration in seconds
|
|
974
|
+
|
|
975
|
+
# Find the best time interval for the given duration and max steps
|
|
976
|
+
best_step = self._find_best_time_step(duration, maxMajorSteps)
|
|
977
|
+
|
|
978
|
+
# Use the calculated datetime step
|
|
979
|
+
scaleDiv = QwtScaleDiv()
|
|
980
|
+
if best_step > 0.0:
|
|
981
|
+
ticks = self.buildTicks(interval, best_step, maxMinorSteps)
|
|
982
|
+
scaleDiv = QwtScaleDiv(interval, ticks)
|
|
983
|
+
|
|
984
|
+
if x1 > x2:
|
|
985
|
+
scaleDiv.invert()
|
|
986
|
+
|
|
987
|
+
return scaleDiv
|
|
988
|
+
|
|
989
|
+
def _find_best_time_step(self, duration, max_steps):
|
|
990
|
+
"""
|
|
991
|
+
Find the best time interval step for the given duration and maximum steps.
|
|
992
|
+
|
|
993
|
+
:param float duration: Total duration in seconds
|
|
994
|
+
:param int max_steps: Maximum number of major ticks
|
|
995
|
+
:return: Best step size in seconds
|
|
996
|
+
"""
|
|
997
|
+
if max_steps < 1:
|
|
998
|
+
max_steps = 1
|
|
999
|
+
|
|
1000
|
+
# Calculate the target step size
|
|
1001
|
+
target_step = duration / max_steps
|
|
1002
|
+
|
|
1003
|
+
# Find the time interval that is closest to our target
|
|
1004
|
+
best_step = self.TIME_INTERVALS[0]
|
|
1005
|
+
min_error = abs(target_step - best_step)
|
|
1006
|
+
|
|
1007
|
+
for interval in self.TIME_INTERVALS:
|
|
1008
|
+
error = abs(target_step - interval)
|
|
1009
|
+
if error < min_error:
|
|
1010
|
+
min_error = error
|
|
1011
|
+
best_step = interval
|
|
1012
|
+
# If the interval is getting much larger than target, stop
|
|
1013
|
+
elif interval > target_step * 2:
|
|
1014
|
+
break
|
|
1015
|
+
|
|
1016
|
+
return float(best_step)
|
|
1017
|
+
|
|
1018
|
+
def buildMinorTicks(self, ticks, maxMinorSteps, stepSize):
|
|
1019
|
+
"""
|
|
1020
|
+
Calculate minor ticks for datetime intervals
|
|
1021
|
+
|
|
1022
|
+
:param list ticks: List of tick arrays
|
|
1023
|
+
:param int maxMinorSteps: Maximum number of minor steps
|
|
1024
|
+
:param float stepSize: Major tick step size
|
|
1025
|
+
"""
|
|
1026
|
+
if maxMinorSteps < 1:
|
|
1027
|
+
return
|
|
1028
|
+
|
|
1029
|
+
# For datetime, create intelligent minor tick intervals
|
|
1030
|
+
minor_step = self._get_minor_step(stepSize, maxMinorSteps)
|
|
1031
|
+
|
|
1032
|
+
if minor_step <= 0:
|
|
1033
|
+
return
|
|
1034
|
+
|
|
1035
|
+
major_ticks = ticks[QwtScaleDiv.MajorTick]
|
|
1036
|
+
if len(major_ticks) < 2:
|
|
1037
|
+
return
|
|
1038
|
+
|
|
1039
|
+
minor_ticks = []
|
|
1040
|
+
|
|
1041
|
+
# Generate minor ticks between each pair of major ticks
|
|
1042
|
+
for i in range(len(major_ticks) - 1):
|
|
1043
|
+
start = major_ticks[i]
|
|
1044
|
+
end = major_ticks[i + 1]
|
|
1045
|
+
|
|
1046
|
+
# Add minor ticks between start and end
|
|
1047
|
+
current = start + minor_step
|
|
1048
|
+
while current < end:
|
|
1049
|
+
minor_ticks.append(current)
|
|
1050
|
+
current += minor_step
|
|
1051
|
+
|
|
1052
|
+
ticks[QwtScaleDiv.MinorTick] = minor_ticks
|
|
1053
|
+
|
|
1054
|
+
def _get_minor_step(self, major_step, max_minor_steps):
|
|
1055
|
+
"""
|
|
1056
|
+
Calculate appropriate minor tick step size for datetime intervals
|
|
1057
|
+
|
|
1058
|
+
:param float major_step: Major tick step size in seconds
|
|
1059
|
+
:param int max_minor_steps: Maximum number of minor steps
|
|
1060
|
+
:return: Minor tick step size in seconds
|
|
1061
|
+
"""
|
|
1062
|
+
# Define sensible minor tick divisions for different time scales
|
|
1063
|
+
if major_step >= 365 * 24 * 60 * 60: # 1 year or more
|
|
1064
|
+
return 30 * 24 * 60 * 60 # 1 month
|
|
1065
|
+
elif major_step >= 30 * 24 * 60 * 60: # 1 month or more
|
|
1066
|
+
return 7 * 24 * 60 * 60 # 1 week
|
|
1067
|
+
elif major_step >= 7 * 24 * 60 * 60: # 1 week or more
|
|
1068
|
+
return 24 * 60 * 60 # 1 day
|
|
1069
|
+
elif major_step >= 24 * 60 * 60: # 1 day or more
|
|
1070
|
+
return 6 * 60 * 60 # 6 hours
|
|
1071
|
+
elif major_step >= 60 * 60: # 1 hour or more
|
|
1072
|
+
return 15 * 60 # 15 minutes
|
|
1073
|
+
elif major_step >= 10 * 60: # 10 minutes or more
|
|
1074
|
+
return 2 * 60 # 2 minutes
|
|
1075
|
+
elif major_step >= 60: # 1 minute or more
|
|
1076
|
+
return 15 # 15 seconds
|
|
1077
|
+
elif major_step >= 10: # 10 seconds or more
|
|
1078
|
+
return 2 # 2 seconds
|
|
1079
|
+
else: # Less than 10 seconds
|
|
1080
|
+
return major_step / max(max_minor_steps, 2)
|
|
@@ -13,6 +13,28 @@ from qwt.tests.utils import TestEnvironment
|
|
|
13
13
|
os.environ[TestEnvironment.UNATTENDED_ENV] = "1"
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
def pytest_addoption(parser):
|
|
17
|
+
"""Add custom command line options to pytest."""
|
|
18
|
+
# See this StackOverflow answer for more information: https://t.ly/9anqz
|
|
19
|
+
parser.addoption(
|
|
20
|
+
"--repeat", action="store", help="Number of times to repeat each test"
|
|
21
|
+
)
|
|
22
|
+
parser.addoption(
|
|
23
|
+
"--show-windows",
|
|
24
|
+
action="store_true",
|
|
25
|
+
default=False,
|
|
26
|
+
help="Display Qt windows during tests (disables QT_QPA_PLATFORM=offscreen)",
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def pytest_configure(config):
|
|
31
|
+
"""Configure pytest based on command line options."""
|
|
32
|
+
if config.option.durations is None:
|
|
33
|
+
config.option.durations = 10 # Default to showing 10 slowest tests
|
|
34
|
+
if not config.getoption("--show-windows"):
|
|
35
|
+
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
|
|
36
|
+
|
|
37
|
+
|
|
16
38
|
def pytest_report_header(config):
|
|
17
39
|
"""Add additional information to the pytest report header."""
|
|
18
40
|
qtbindings_version = qtpy.PYSIDE_VERSION
|
|
@@ -24,14 +46,6 @@ def pytest_report_header(config):
|
|
|
24
46
|
]
|
|
25
47
|
|
|
26
48
|
|
|
27
|
-
def pytest_addoption(parser):
|
|
28
|
-
"""Add custom command line options to pytest."""
|
|
29
|
-
# See this StackOverflow answer for more information: https://t.ly/9anqz
|
|
30
|
-
parser.addoption(
|
|
31
|
-
"--repeat", action="store", help="Number of times to repeat each test"
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
35
49
|
def pytest_generate_tests(metafunc):
|
|
36
50
|
"""Generate tests for the given metafunc."""
|
|
37
51
|
# See this StackOverflow answer for more information: https://t.ly/9anqz
|
|
@@ -195,7 +195,7 @@ class CpuStat:
|
|
|
195
195
|
return 100.0 * userDelta / totalDelta, 100.0 * systemDelta / totalDelta
|
|
196
196
|
|
|
197
197
|
def upTime(self):
|
|
198
|
-
result = QTime()
|
|
198
|
+
result = QTime(0, 0, 0)
|
|
199
199
|
for item in self.procValues:
|
|
200
200
|
result = result.addSecs(int(0.01 * item))
|
|
201
201
|
return result
|
|
@@ -333,6 +333,13 @@ class QwtPlainTextEngine(QwtTextEngine):
|
|
|
333
333
|
:param str text: Text to be rendered
|
|
334
334
|
"""
|
|
335
335
|
painter.save()
|
|
336
|
+
|
|
337
|
+
# Get and configure font for better rendering of rotated text
|
|
338
|
+
font = painter.font()
|
|
339
|
+
# Disable hinting to avoid character misalignment in rotated text
|
|
340
|
+
font.setHintingPreference(QFont.PreferNoHinting)
|
|
341
|
+
painter.setFont(font)
|
|
342
|
+
|
|
336
343
|
qwtUnscaleFont(painter)
|
|
337
344
|
painter.drawText(rect, flags, text)
|
|
338
345
|
painter.restore()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|