Skip to content

Commit 9667104

Browse files
authored
Heatmap plot (#44)
feat: add heatmap live plot
1 parent 7988273 commit 9667104

File tree

82 files changed

+468
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+468
-4
lines changed

.github/FUNDING.yml

100644100755
File mode changed.

README.md

100644100755
Lines changed: 1 addition & 0 deletions

pglive/__init__.py

100644100755
File mode changed.

pglive/examples_pyqt5/__init__.py

100644100755
File mode changed.

pglive/examples_pyqt5/all_plot_types.py

100644100755
File mode changed.

pglive/examples_pyqt5/axis.py

100644100755
File mode changed.

pglive/examples_pyqt5/candlestick_plot.py

100644100755
File mode changed.

pglive/examples_pyqt5/categorized_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyqt5/crop_offset_to_data.py

100644100755
File mode changed.

pglive/examples_pyqt5/crosshair.py

100644100755
File mode changed.

pglive/examples_pyqt5/designer_example/__init__.py

100644100755
File mode changed.

pglive/examples_pyqt5/designer_example/main_example.py

100644100755
File mode changed.

pglive/examples_pyqt5/designer_example/win_template.py

100644100755
File mode changed.

pglive/examples_pyqt5/designer_example/win_template.ui

100644100755
File mode changed.

pglive/examples_pyqt5/heatmap_plot.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import signal
2+
import time
3+
from threading import Thread
4+
import pglive.examples_pyqt5 as examples
5+
import numpy.random
6+
import pyqtgraph as pg
7+
from PyQt5.QtWidgets import QWidget, QGridLayout
8+
9+
10+
from pglive.kwargs import Axis
11+
from pglive.sources.data_connector import DataConnector
12+
from pglive.sources.live_HeatMap import LiveHeatMap
13+
from pglive.sources.live_axis import LiveAxis
14+
from pglive.sources.live_plot_widget import LivePlotWidget
15+
16+
"""
17+
HeatMap is displayed in this example.
18+
"""
19+
# Get color map
20+
cmap = pg.colormap.get("CET-D1")
21+
# Create Heat map plot item
22+
# grid_pen is used to draw a grid, remove if you don't want any grid
23+
# counts_pen is used to draw point counts, remove if you don't want any grid
24+
plot = LiveHeatMap(colormap=cmap, grid_pen=pg.mkPen("red"), counts_pen=pg.mkPen("white"))
25+
26+
resolution = 10 # 10 x 10 pixels
27+
left_labels = [f"Y{i}" for i in range(resolution)]
28+
bottom_labels = [f"X{i}" for i in range(resolution)]
29+
30+
# Set Axis.SHOW_ALL_CATEGORIES: True if you want to always show all category ticks
31+
left_axis = LiveAxis("left", tick_angle=0,
32+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels, Axis.SHOW_ALL_CATEGORIES: True})
33+
right_axis = LiveAxis("right", tick_angle=0,
34+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels,
35+
Axis.SHOW_ALL_CATEGORIES: False})
36+
top_axis = LiveAxis("top", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels,
37+
Axis.SHOW_ALL_CATEGORIES: True})
38+
bottom_axis = LiveAxis("bottom", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels,
39+
Axis.SHOW_ALL_CATEGORIES: False})
40+
41+
view_1 = LivePlotWidget(title="Heat map plot with counts and grid @ 1Hz",
42+
axisItems={'top': top_axis, 'bottom': bottom_axis, 'left': left_axis, 'right': right_axis})
43+
view_1.addItem(plot)
44+
45+
# Get color map
46+
cmap_2 = pg.colormap.get("plasma")
47+
# Create Heat map plot item
48+
plot_2 = LiveHeatMap(colormap=cmap_2)
49+
50+
resolution_2 = 20 # 20 x 20 pixels
51+
left_labels_2 = [f"Y{i}" for i in range(resolution_2)]
52+
bottom_labels_2 = [f"X{i}" for i in range(resolution_2)]
53+
54+
# Set Axis.SHOW_ALL_CATEGORIES: True if you want to always show all category ticks
55+
left_axis_2 = LiveAxis("left", tick_angle=0,
56+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels_2,
57+
Axis.SHOW_ALL_CATEGORIES: True})
58+
right_axis_2 = LiveAxis("right", tick_angle=0,
59+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels_2,
60+
Axis.SHOW_ALL_CATEGORIES: False})
61+
top_axis_2 = LiveAxis("top", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels_2,
62+
Axis.SHOW_ALL_CATEGORIES: True})
63+
bottom_axis_2 = LiveAxis("bottom", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels_2,
64+
Axis.SHOW_ALL_CATEGORIES: False})
65+
66+
view_2 = LivePlotWidget(title="Heat map plot @ 10Hz",
67+
axisItems={'top': top_axis_2, 'bottom': bottom_axis_2, 'left': left_axis_2,
68+
'right': right_axis_2})
69+
view_2.addItem(plot_2)
70+
71+
# Setup layout to display all plots and histograms
72+
plots_view = QWidget()
73+
plots_view.setContentsMargins(0, 0, 0, 0)
74+
plots_view.setLayout(QGridLayout())
75+
plots_view.layout().setSpacing(0)
76+
plots_view.layout().addWidget(view_1, 0, 0)
77+
plots_view.layout().addWidget(plot.histogram, 0, 1)
78+
plots_view.layout().addWidget(view_2, 1, 0)
79+
plots_view.layout().addWidget(plot_2.histogram, 1, 1)
80+
plots_view.show()
81+
data_connector = DataConnector(plot)
82+
data_connector_2 = DataConnector(plot_2)
83+
84+
85+
def heatmap_generator(data_connector, resolution, bottom_labels, left_labels, timeout=1):
86+
while examples.running:
87+
heatmap = []
88+
for i in range(resolution):
89+
heatmap.append(numpy.random.randint(0, 1000, resolution))
90+
data_connector.cb_set_data(bottom_labels, left_labels, heatmap=heatmap)
91+
time.sleep(timeout)
92+
93+
94+
Thread(target=heatmap_generator, args=(data_connector, resolution, bottom_labels, left_labels)).start()
95+
Thread(target=heatmap_generator, args=(data_connector_2, resolution_2, bottom_labels_2, left_labels_2, 0.1)).start()
96+
signal.signal(signal.SIGINT, lambda sig, frame: examples.stop())
97+
examples.app.exec()
98+
examples.stop()

pglive/examples_pyqt5/horizontal_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyqt5/leading_line.py

100644100755
File mode changed.

pglive/examples_pyqt5/line_plot.py

100644100755
File mode changed.

pglive/examples_pyqt5/live_plot_range.py

100644100755
File mode changed.

pglive/examples_pyqt5/one_plot_multiple_plot_rates.py

100644100755
File mode changed.

pglive/examples_pyqt5/pause_resume.py

100644100755
File mode changed.

pglive/examples_pyqt5/plot_rate.py

100644100755
File mode changed.

pglive/examples_pyqt5/scatter_plot.py

100644100755
File mode changed.

pglive/examples_pyqt5/update_rate.py

100644100755
File mode changed.

pglive/examples_pyqt5/vertical_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyqt5/vertical_bar_plot_color.py

100644100755
File mode changed.

pglive/examples_pyqt6/__init__.py

100644100755
File mode changed.

pglive/examples_pyqt6/all_plot_types.py

100644100755
File mode changed.

pglive/examples_pyqt6/axis.py

100644100755
File mode changed.

pglive/examples_pyqt6/candlestick_plot.py

100644100755
File mode changed.

pglive/examples_pyqt6/categorized_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyqt6/crop_offset_to_data.py

100644100755
File mode changed.

pglive/examples_pyqt6/crosshair.py

100644100755
File mode changed.

pglive/examples_pyqt6/designer_example/__init__.py

100644100755
File mode changed.

pglive/examples_pyqt6/designer_example/main_example.py

100644100755
File mode changed.

pglive/examples_pyqt6/designer_example/win_template.py

100644100755
File mode changed.

pglive/examples_pyqt6/designer_example/win_template.ui

100644100755
File mode changed.

pglive/examples_pyqt6/heatmap_plot.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import signal
2+
import time
3+
from threading import Thread
4+
5+
import numpy.random
6+
import pyqtgraph as pg
7+
from PyQt6.QtWidgets import QWidget, QGridLayout
8+
9+
import pglive.examples_pyqt6 as examples
10+
from pglive.kwargs import Axis
11+
from pglive.sources.data_connector import DataConnector
12+
from pglive.sources.live_HeatMap import LiveHeatMap
13+
from pglive.sources.live_axis import LiveAxis
14+
from pglive.sources.live_plot_widget import LivePlotWidget
15+
16+
"""
17+
HeatMap is displayed in this example.
18+
"""
19+
# Get color map
20+
cmap = pg.colormap.get("CET-D1")
21+
# Create Heat map plot item
22+
# grid_pen is used to draw a grid, remove if you don't want any grid
23+
# counts_pen is used to draw point counts, remove if you don't want any grid
24+
plot = LiveHeatMap(colormap=cmap, grid_pen=pg.mkPen("red"), counts_pen=pg.mkPen("white"))
25+
26+
resolution = 10 # 10 x 10 pixels
27+
left_labels = [f"Y{i}" for i in range(resolution)]
28+
bottom_labels = [f"X{i}" for i in range(resolution)]
29+
30+
# Set Axis.SHOW_ALL_CATEGORIES: True if you want to always show all category ticks
31+
left_axis = LiveAxis("left", tick_angle=0,
32+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels, Axis.SHOW_ALL_CATEGORIES: True})
33+
right_axis = LiveAxis("right", tick_angle=0,
34+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels,
35+
Axis.SHOW_ALL_CATEGORIES: False})
36+
top_axis = LiveAxis("top", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels,
37+
Axis.SHOW_ALL_CATEGORIES: True})
38+
bottom_axis = LiveAxis("bottom", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels,
39+
Axis.SHOW_ALL_CATEGORIES: False})
40+
41+
view_1 = LivePlotWidget(title="Heat map plot with counts and grid @ 1Hz",
42+
axisItems={'top': top_axis, 'bottom': bottom_axis, 'left': left_axis, 'right': right_axis})
43+
view_1.addItem(plot)
44+
45+
# Get color map
46+
cmap_2 = pg.colormap.get("plasma")
47+
# Create Heat map plot item
48+
plot_2 = LiveHeatMap(colormap=cmap_2)
49+
50+
resolution_2 = 20 # 20 x 20 pixels
51+
left_labels_2 = [f"Y{i}" for i in range(resolution_2)]
52+
bottom_labels_2 = [f"X{i}" for i in range(resolution_2)]
53+
54+
# Set Axis.SHOW_ALL_CATEGORIES: True if you want to always show all category ticks
55+
left_axis_2 = LiveAxis("left", tick_angle=0,
56+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels_2,
57+
Axis.SHOW_ALL_CATEGORIES: True})
58+
right_axis_2 = LiveAxis("right", tick_angle=0,
59+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels_2,
60+
Axis.SHOW_ALL_CATEGORIES: False})
61+
top_axis_2 = LiveAxis("top", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels_2,
62+
Axis.SHOW_ALL_CATEGORIES: True})
63+
bottom_axis_2 = LiveAxis("bottom", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels_2,
64+
Axis.SHOW_ALL_CATEGORIES: False})
65+
66+
view_2 = LivePlotWidget(title="Heat map plot @ 10Hz",
67+
axisItems={'top': top_axis_2, 'bottom': bottom_axis_2, 'left': left_axis_2,
68+
'right': right_axis_2})
69+
view_2.addItem(plot_2)
70+
71+
# Setup layout to display all plots and histograms
72+
plots_view = QWidget()
73+
plots_view.setContentsMargins(0, 0, 0, 0)
74+
plots_view.setLayout(QGridLayout())
75+
plots_view.layout().setSpacing(0)
76+
plots_view.layout().addWidget(view_1, 0, 0)
77+
plots_view.layout().addWidget(plot.histogram, 0, 1)
78+
plots_view.layout().addWidget(view_2, 1, 0)
79+
plots_view.layout().addWidget(plot_2.histogram, 1, 1)
80+
plots_view.show()
81+
data_connector = DataConnector(plot)
82+
data_connector_2 = DataConnector(plot_2)
83+
84+
85+
def heatmap_generator(data_connector, resolution, bottom_labels, left_labels, timeout=1):
86+
while examples.running:
87+
heatmap = []
88+
for i in range(resolution):
89+
heatmap.append(numpy.random.randint(0, 1000, resolution))
90+
data_connector.cb_set_data(bottom_labels, left_labels, heatmap=heatmap)
91+
time.sleep(timeout)
92+
93+
94+
Thread(target=heatmap_generator, args=(data_connector, resolution, bottom_labels, left_labels)).start()
95+
Thread(target=heatmap_generator, args=(data_connector_2, resolution_2, bottom_labels_2, left_labels_2, 0.1)).start()
96+
signal.signal(signal.SIGINT, lambda sig, frame: examples.stop())
97+
examples.app.exec()
98+
examples.stop()

pglive/examples_pyqt6/horizontal_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyqt6/leading_line.py

100644100755
File mode changed.

pglive/examples_pyqt6/line_plot.py

100644100755
File mode changed.

pglive/examples_pyqt6/live_plot_range.py

100644100755
File mode changed.

pglive/examples_pyqt6/one_plot_multiple_plot_rates.py

100644100755
File mode changed.

pglive/examples_pyqt6/pause_resume.py

100644100755
File mode changed.

pglive/examples_pyqt6/plot_rate.py

100644100755
File mode changed.

pglive/examples_pyqt6/scatter_plot.py

100644100755
File mode changed.

pglive/examples_pyqt6/update_rate.py

100644100755
File mode changed.

pglive/examples_pyqt6/vertical_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyqt6/vertical_bar_plot_color.py

100644100755
File mode changed.

pglive/examples_pyside6/__init__.py

100644100755
File mode changed.

pglive/examples_pyside6/all_plot_types.py

100644100755
File mode changed.

pglive/examples_pyside6/axis.py

100644100755
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
from math import sin
44
from threading import Thread
55
from time import sleep
6-
7-
import pyqtgraph as pg # type: ignore
8-
96
import pglive.examples_pyside6 as examples
7+
import pyqtgraph as pg # type: ignore
108
from pglive.kwargs import Axis
119
from pglive.sources.data_connector import DataConnector
1210
from pglive.sources.live_axis import LiveAxis

pglive/examples_pyside6/candlestick_plot.py

100644100755
File mode changed.

pglive/examples_pyside6/categorized_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyside6/crop_offset_to_data.py

100644100755
File mode changed.

pglive/examples_pyside6/crosshair.py

100644100755
File mode changed.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import signal
2+
import time
3+
from threading import Thread
4+
import pglive.examples_pyside6 as examples
5+
import numpy.random
6+
import pyqtgraph as pg
7+
from PySide6.QtWidgets import QWidget, QGridLayout
8+
9+
10+
from pglive.kwargs import Axis
11+
from pglive.sources.data_connector import DataConnector
12+
from pglive.sources.live_HeatMap import LiveHeatMap
13+
from pglive.sources.live_axis import LiveAxis
14+
from pglive.sources.live_plot_widget import LivePlotWidget
15+
16+
"""
17+
HeatMap is displayed in this example.
18+
"""
19+
# Get color map
20+
cmap = pg.colormap.get("CET-D1")
21+
# Create Heat map plot item
22+
# grid_pen is used to draw a grid, remove if you don't want any grid
23+
# counts_pen is used to draw point counts, remove if you don't want any grid
24+
plot = LiveHeatMap(colormap=cmap, grid_pen=pg.mkPen("red"), counts_pen=pg.mkPen("white"))
25+
26+
resolution = 10 # 10 x 10 pixels
27+
left_labels = [f"Y{i}" for i in range(resolution)]
28+
bottom_labels = [f"X{i}" for i in range(resolution)]
29+
30+
# Set Axis.SHOW_ALL_CATEGORIES: True if you want to always show all category ticks
31+
left_axis = LiveAxis("left", tick_angle=0,
32+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels, Axis.SHOW_ALL_CATEGORIES: True})
33+
right_axis = LiveAxis("right", tick_angle=0,
34+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels,
35+
Axis.SHOW_ALL_CATEGORIES: False})
36+
top_axis = LiveAxis("top", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels,
37+
Axis.SHOW_ALL_CATEGORIES: True})
38+
bottom_axis = LiveAxis("bottom", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels,
39+
Axis.SHOW_ALL_CATEGORIES: False})
40+
41+
view_1 = LivePlotWidget(title="Heat map plot with counts and grid @ 1Hz",
42+
axisItems={'top': top_axis, 'bottom': bottom_axis, 'left': left_axis, 'right': right_axis})
43+
view_1.addItem(plot)
44+
45+
# Get color map
46+
cmap_2 = pg.colormap.get("plasma")
47+
# Create Heat map plot item
48+
plot_2 = LiveHeatMap(colormap=cmap_2)
49+
50+
resolution_2 = 20 # 20 x 20 pixels
51+
left_labels_2 = [f"Y{i}" for i in range(resolution_2)]
52+
bottom_labels_2 = [f"X{i}" for i in range(resolution_2)]
53+
54+
# Set Axis.SHOW_ALL_CATEGORIES: True if you want to always show all category ticks
55+
left_axis_2 = LiveAxis("left", tick_angle=0,
56+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels_2,
57+
Axis.SHOW_ALL_CATEGORIES: True})
58+
right_axis_2 = LiveAxis("right", tick_angle=0,
59+
**{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: left_labels_2,
60+
Axis.SHOW_ALL_CATEGORIES: False})
61+
top_axis_2 = LiveAxis("top", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels_2,
62+
Axis.SHOW_ALL_CATEGORIES: True})
63+
bottom_axis_2 = LiveAxis("bottom", tick_angle=0, **{Axis.TICK_FORMAT: Axis.CATEGORY, Axis.CATEGORIES: bottom_labels_2,
64+
Axis.SHOW_ALL_CATEGORIES: False})
65+
66+
view_2 = LivePlotWidget(title="Heat map plot @ 10Hz",
67+
axisItems={'top': top_axis_2, 'bottom': bottom_axis_2, 'left': left_axis_2,
68+
'right': right_axis_2})
69+
view_2.addItem(plot_2)
70+
71+
# Setup layout to display all plots and histograms
72+
plots_view = QWidget()
73+
plots_view.setContentsMargins(0, 0, 0, 0)
74+
plots_view.setLayout(QGridLayout())
75+
plots_view.layout().setSpacing(0)
76+
plots_view.layout().addWidget(view_1, 0, 0)
77+
plots_view.layout().addWidget(plot.histogram, 0, 1)
78+
plots_view.layout().addWidget(view_2, 1, 0)
79+
plots_view.layout().addWidget(plot_2.histogram, 1, 1)
80+
plots_view.show()
81+
data_connector = DataConnector(plot)
82+
data_connector_2 = DataConnector(plot_2)
83+
84+
85+
def heatmap_generator(data_connector, resolution, bottom_labels, left_labels, timeout=1):
86+
while examples.running:
87+
heatmap = []
88+
for i in range(resolution):
89+
heatmap.append(numpy.random.randint(0, 1000, resolution))
90+
data_connector.cb_set_data(bottom_labels, left_labels, heatmap=heatmap)
91+
time.sleep(timeout)
92+
93+
94+
Thread(target=heatmap_generator, args=(data_connector, resolution, bottom_labels, left_labels)).start()
95+
Thread(target=heatmap_generator, args=(data_connector_2, resolution_2, bottom_labels_2, left_labels_2, 0.1)).start()
96+
signal.signal(signal.SIGINT, lambda sig, frame: examples.stop())
97+
examples.app.exec()
98+
examples.stop()

pglive/examples_pyside6/horizontal_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyside6/leading_line.py

100644100755
File mode changed.

pglive/examples_pyside6/line_plot.py

100644100755
File mode changed.

pglive/examples_pyside6/live_plot_range.py

100644100755
File mode changed.

pglive/examples_pyside6/one_plot_multiple_plot_rates.py

100644100755
File mode changed.

pglive/examples_pyside6/pause_resume.py

100644100755
File mode changed.

pglive/examples_pyside6/plot_rate.py

100644100755
File mode changed.

pglive/examples_pyside6/scatter_plot.py

100644100755
File mode changed.

pglive/examples_pyside6/update_rate.py

100644100755
File mode changed.

pglive/examples_pyside6/vertical_bar_plot.py

100644100755
File mode changed.

pglive/examples_pyside6/vertical_bar_plot_color.py

100644100755
File mode changed.

pglive/kwargs.py

100644100755
File mode changed.

pglive/sources/__init__.py

100644100755
File mode changed.

pglive/sources/data_connector.py

100644100755
File mode changed.

0 commit comments

Comments
 (0)