[PYTHON] [pyqtgraph] Add region to the graph and link it with the graph region

Thing you want to do

I want to add a region to the main graph and display that region in another graph region.gif

Create while referring to Crosshair / Mouse interaction of pyqtgraph.exsamples.run () exsample.gif

environment

Mac OS Python 3.8.5

PyQt5 5.15.2 PyQt5-sip 12.8.1 pyqtgraph 0.11.1

pip install PyQt5 PyQt5-sip pyqtgraph

pyqtgraph.exsamples

import pyqtgraph.examples as ex
ex.run()

You can see various sample graphs at. I referred to Crosshair / Mouse interaction this time. exsamples.png

code

I'm using numpy for plotting. pip install numpy

"""Add region to the graph and link it with the graph region"""

import dataclasses
from typing import Optional
import sys

import numpy as np
from PyQt5 import QtWidgets, QtCore
import pyqtgraph as pg

SAMPLE_DATA1 = np.random.rand(500) * 10
SAMPLE_DATA2 = 10 + np.random.rand(500) * 10
SAMPLE_DATA3 = 20 + np.random.rand(500) * 10


@dataclasses.dataclass
class AddRegionWidget(pg.GraphicsLayoutWidget):
    """Main screen
    Attributes #
    ----------
    parent: Optional[QtWidgets.QWidget] default=None
Parent screen
    main_plotter: pyqtgraph.graphicsItems.PlotItem.PlotItem.PlotItem
Main graph
    zoom_plotter: pyqtgraph.graphicsItems.PlotItem.PlotItem.PlotItem
A graph that zooms the main graph in the region
    region: pyqtgraph.graphicsItems.LinearRegionItem.LinearRegionItem
        zoom_region that specifies the x-axis region of the plotter
    """
    parent: Optional[QtWidgets.QWidget] = None

    def __post_init__(self) -> None:
        """Superclass loading and plot,region added"""
        super(AddRegionWidget, self).__init__(parent=self.parent)

        self.add_plot()
        self.add_region()
        self.connect_slot()

    def add_plot(self) -> None:
        """add plot"""
        self.main_plotter = self.addPlot(row=0, col=0)
        self.main_plotter.showGrid(x=True, y=True, alpha=0.8)
        main_curve1 = self.main_plotter.plot(pen=pg.mkPen('#f00'))
        main_curve2 = self.main_plotter.plot(pen=pg.mkPen('#0f0'))
        main_curve3 = self.main_plotter.plot(pen=pg.mkPen('#00f'))
        main_curve1.setData(SAMPLE_DATA1)
        main_curve2.setData(SAMPLE_DATA2)
        main_curve3.setData(SAMPLE_DATA3)

        self.zoom_plotter = self.addPlot(row=0, col=1)
        #Adjust the y-axis according to the value
        self.zoom_plotter.setAutoVisible(y=True)
        self.zoom_plotter.showGrid(x=True, y=True, alpha=0.8)
        zoom_curve1 = self.zoom_plotter.plot(pen=pg.mkPen('#f00'))
        zoom_curve2 = self.zoom_plotter.plot(pen=pg.mkPen('#0f0'))
        zoom_curve3 = self.zoom_plotter.plot(pen=pg.mkPen('#00f'))
        zoom_curve1.setData(SAMPLE_DATA1)
        zoom_curve2.setData(SAMPLE_DATA2)
        zoom_curve3.setData(SAMPLE_DATA3)

        self.zoom_plotter.setXRange(0.0, len(SAMPLE_DATA1) / 8, padding=0)

        self.ci.layout.setColumnStretchFactor(0, 8)
        self.ci.layout.setColumnStretchFactor(1, 5)

    def add_region(self) -> None:
        """Add region"""
        self.region = pg.LinearRegionItem()
        #Region height setting. There are multiple regions&If they overlap, the one with the higher Z can be operated.(Since there is only one this time, set it to 10 appropriately)
        self.region.setZValue(10)
        self.main_plotter.addItem(self.region, ignoreBounds=True)
        self.update_region()

    def connect_slot(self) -> None:
        """slot connection"""
        self.region.sigRegionChanged.connect(self.update_zoom_plotter)
        self.zoom_plotter.sigRangeChanged.connect(self.update_region)

    @QtCore.pyqtSlot()
    def update_zoom_plotter(self) -> None:
        """self when the region moves.zoom_Change plotter area"""
        self.region.setZValue(10)
        min_x, max_x = self.region.getRegion()
        self.zoom_plotter.setXRange(min_x, max_x, padding=0)

    @QtCore.pyqtSlot()
    def update_region(self) -> None:
        """self.zoom_Change the region of the region when the plotter moves
viewRange returns the display range of the graph. The type is
        [[Xmin, Xmax], [Ymin, Ymax]]
        """
        rgn = self.zoom_plotter.viewRange()[0]
        self.region.setRegion(rgn)


def main() -> None:
    app = QtWidgets.QApplication(sys.argv)
    window = AddRegionWidget(parent=None)
    window.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Details

Change the zoom_plotter range when the region changes

    @QtCore.pyqtSlot()
    def update_zoom_plotter(self) -> None:
        """self when the region moves.zoom_Change plotter area"""
        self.region.setZValue(10)
        min_x, max_x = self.region.getRegion()
        self.zoom_plotter.setXRange(min_x, max_x, padding=0)

min_x, max_x are the x-coordinates of the region. ex) min_x=231.1511878655732 max_x=293.6511878655732 It is specified in the x-axis range of zoom_potter.

padding = 0 is an image with no margins. For example, when self.zoom_plotter.setXRange (100, 1000, padding = 0.1), the actual displayed range is [100 * (1-0.1), 1000 * (1 + 0.1)] [90, 1100 ] .

I set it to 0 because I want to match the range of region and the range of zoom_plotter.

Change the range of region when the range of zoom_plotter changes

    @QtCore.pyqtSlot()
    def update_region(self) -> None:
        """self.zoom_Change the region of the region when the plotter moves
viewRange returns the display range of the graph. The type is
        [[Xmin: float, Xmax: float], [Ymin: float, Ymax: float]]
        """
        rgn = self.zoom_plotter.viewRange()[0]
        self.region.setRegion(rgn)

When you change the range of zoom_plotter directly, the range of region is adjusted accordingly. The range of [Xmin: float, Xmax: float] is set to region with setRegion.

Other region settings

Creating a landscape region horizontal_region = pg.LinearRegionItem(orientation='horizontal') region Color settings in the region region = pg.LinearRegionItem(brush=pg.mkBrush('#f004')) You can pass colors other than \ #RGBA.

| ‘c’ | one of: r, g, b, c, m, y, k, w | | -------------- | ------------------------------------------------------------ | | R, G, B, [A] | integers 0-255 | | (R, G, B, [A]) | tuple of integers 0-255 | | float | greyscale, 0.0-1.0 | | int | see intColor() | | (int, hues) | see intColor() | | “RGB” | hexadecimal strings; may begin with ‘#’ | | “RGBA” | | | “RRGGBB” | | | “RRGGBBAA” | | | QColor | QColor instance; makes a copy. |

PyQtGraph’s Helper Functions — pyqtgraph 0.11.1.dev0 documentation

region Border color setting (color can be specified in the same way as above) region = pg.LinearRegionItem(pen=pg.mkPen('#fff'))

In-region color setting when the cursor is on the region region = pg.LinearRegionItem(hoverBrush=pg.mkBrush('#fff4'))

Border color setting when the cursor is on the border of a region region = pg.LinearRegionItem(hoverPen=pg.mkPen('#f00'))

reference

Crosshair / Mouse interaction in pyqtgraph.exsamples.run ()

region LinearRegionItem — pyqtgraph0.11.1.dev0 documentation

region color setting PyQtGraph’s Helper Functions — pyqtgraph 0.11.1.dev0 documentation

Recommended Posts

[pyqtgraph] Add region to the graph and link it with the graph region
Convert the spreadsheet to CSV and upload it to Cloud Storage with Cloud Functions
MessagePack-Try to link Java and Python with RPC
Scraping the holojour and displaying it with CLI
Draw a graph with PyQtGraph Part 5-Increase the Y-axis
Add information to the bottom of the figure with Matplotlib
Save the graph drawn by pyqtgraph to an image
[Neo4J] ④ Try to handle the graph structure with Cypher
POST the image with json and receive it with flask
Display / update the graph according to the input with PySimpleGui
Let's add it to the environment variable from the command ~
Read the csv file with jupyter notebook and write the graph on top of it
It is easy to execute SQL with Python and output the result in Excel
POST the image selected on the website with multipart / form-data and save it to Amazon S3! !!
Recursively get the Excel list in a specific folder with python and write it to Excel.
Try to link iTunes and Hue collection case with MQTT
Return the image data with Flask of Python and draw it to the canvas element of HTML
"Deep copy" and "Shallow copy" to understand with the smallest example
The usual way to add a Kernel with Jupyter Notebook
[Python] What is pip? Explain the command list and how to use it with actual examples
Process the gzip file UNLOADed with Redshift with Python of Lambda, gzip it again and upload it to S3
Send the temperature, humidity, etc. measured by SensorTag to Ambient via Raspberry Pi 3 and graph it.
Find the white Christmas rate by prefecture with Python and map it to a map of Japan
Measure temperature, humidity, etc. with SensorTag and send it to Ambient via Raspberry Pi 3 to graph it Part 2
It's faster to add than to join and extend the list, right?
Repeat with While. Scripts to Tweet and search from the terminal
The strongest way to use MeCab and CaboCha with Google Colab
To improve the reusability and maintainability of workflows created with Luigi
Convert the result of python optparse to dict and utilize it
Code Python to check and graph if it follows Benford's law
Draw a graph with Julia + PyQtGraph (2)
Link to get started with python
Add fields to features with ArcPy
Draw a graph with Julia + PyQtGraph (1)
Draw a graph with Julia + PyQtGraph (3)
Output the call graph with PyCallGraph
The easiest way to try PyQtGraph
Output the report as PDF from DB with Python and automatically attach it to an email and send it
I ran GhostScript with python, split the PDF into pages, and converted it to a JPEG image.
Read the data of the NFC reader connected to Raspberry Pi 3 with Python and send it to openFrameworks with OSC
Upload data to s3 of aws with a command and update it, and delete the used data (on the way)
Memorandum (Add name only to people with the same surname in the list)
Calculate the shortest route of a graph with Dijkstra's algorithm and Python
Specify the browser to use with Jupyter Notebook. Especially Mac. (And Vivaldi)
Connect to VPN with your smartphone and turn off / on the server
I tried to express sadness and joy with the stable marriage problem.
How to get the date and time difference in seconds with python
Add 95% confidence intervals on both sides to the diagram with Python / Matplotlib
Scrap the published csv with Github Action and publish it on Github Pages
Extract the TOP command result with USER and output it as CSV
I set the environment variable with Docker and displayed it in Python
I vectorized the chord of the song with word2vec and visualized it with t-SNE
Search for Twitter keywords with tweepy and write the results to Excel
I tried to learn the angle from sin and cos with chainer
Read the graph image with OpenCV and get the coordinates of the final point of the graph
I tried with the top 100 PyPI packages> I tried to graph the packages installed on Python
Read CSV file with Python and convert it to DataFrame as it is
Start the webcam to take a still image and save it locally
[python] Send the image captured from the webcam to the server and save it
How to query BigQuery with Kubeflow Pipelines and save the result and notes
I tried to control the network bandwidth and delay with the tc command