[PYTHON] Create a heatmap with pyqtgraph

Introduction

I had the opportunity to create a heatmap in real time, and I used pyqtgraph because I was worried about the processing speed of matplotlib. However, pyqtgraph has little information in Japanese, and there is no color bar used for heat map by default, so I will describe the results of various investigations.

environment

Mac OS Python 3.8.1

Installed with pip

colour 0.1.5 numpy 1.19.2 pgcolorbar 1.0.0 PyQt5 5.15.2 PyQt5-sip 12.8.1 pyqtgraph 0.11.0

pip install colour numpy pgcolorbar PyQt5 PyQt5-sip pyqtgraph

pgcolorbar A library that creates color bars with pyqtgraph. After installing with pip, you can see the demo with the following command.

pgcolorbar_demo

Details

Real-time drawing will be postponed this time and only the heat map will be explained. Finally, create the following screen. (2021/01/19 before correction) heatmap.gif

Sample data

This is sample data used for explanation. I'm doing various things, but it doesn't mean anything. Since it is a two-dimensional array, there is no RGB information.

#Sample array
data = np.random.normal(size=(200, 200))
data[40:80, 40:120] += 4
data = pg.gaussianFilter(data, (15, 15))
data += np.random.normal(size=(200, 200)) * 0.1

Minimum code for image display (assumed)

After that, add to the code below to create a heat map. What you are doing

  1. Create window
  2. Image creation
  3. Add image to view
  4. Create a graph (for displaying the coordinates of the image)
  5. Add the view created in 3. to the graph
  6. Add a graph to the window
  7. Display

is

"""Minimum code to display an image with pyqtgraph(To)"""
import sys

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


#Sample data code omitted

#GUI control object
app = QtWidgets.QApplication(sys.argv)
#Window creation
window = pg.GraphicsLayoutWidget()
#Image object creation&Set image
image = pg.ImageItem()
image.setImage(data)
#Create a box to store images&Set image object
view_box = pg.ViewBox()
view_box.addItem(image)
#Plot object creation&View created above_set box
plot = pg.PlotItem(viewBox=view_box)
#Add plot to window
window.addItem(plot)
#Window display
window.show()
#The end of the program
sys.exit(app.exec_())

If you execute it in this state, the following screen will be created.

minimum.png

ViewBox Add the following:

view_box.setAspectLocked(lock=True)

Fixed the aspect ratio of view_box. Because the image size is a 200x200 square, I don't want the shape to change when the window size changes.

Added peripheral code

view_box = pg.ViewBox()
view_box.setAspectLocked(lock=True)  # Add
view_box.addItem(image)

Screen when executed seihoukei.png

PlotItem There is no place to edit.

ImageItem The added parts and their surroundings are described below.

################## Add #######################
from colour import Color

blue, red = Color('blue'), Color('red')
colors = blue.range_to(red, 256)
colors_array = np.array([np.array(color.get_rgb()) * 255 for color in colors])
look_up_table = colors_array.astype(np.uint8)
################## Add #######################

image = pg.ImageItem()
image.setLookupTable(look_up_table)  # Add
image.setImage(data)

Screen when executed lookuptable.png

from colour import Color I will describe the details of the contents. What you want to create in this section is a two-dimensional array of RGB information (unsigned 8-bit integer) [[R, G, B], [R, G, B], ... [R, G, B],]

blue, red = Color('blue'), Color('red')
# >>> <class 'colour.Color'> <class 'colour.Color'>

blue.get_rgb()
# >>> (0.0, 0.0, 1.0)

colors = blue.range_to(red, 256) #256 divisions of colors from blue to red
# >>>If you look at the contents in the generator list
# >>> [<Color blue>, <Color #0004ff>, <Color #0008ff>, ..., <Color red>]

colors_array = np.array([np.array(color.get_rgb()) * 255 for color in colors])
# >>> [[  0.   0. 255.]
#      [  0.   4. 255.]
#      [  0.   8. 255.]
#      ...
#      [255.   0.   0.]] float64

look_up_table = colors_array.astype(np.uint8) #Convert to unsigned 8-bit integer
# >>> [[  0   0 255]
#      [  0   3 255]
#      ...
#      [255   0   0]] uint8

Look Up Table

Table that looks up (references) the output color data corresponding to the input color data 1st LUT Basics | TV Logic

It seems. (I'm sorry I'm not very familiar with it ...) It is an image like a table that converts the value of sample data into RGB information.

2021/01/19 postscript

image.setOpts(axisOrder='row-major')

Please add the above code. By default, pg.ImageItem reads a 2D array in columns-> rows. Since a 2D array is basically a matrix, it is necessary to read it in rows-> columns. If not written, it will be read like a transposed matrix of the original data.

Modified code

################## Add #######################
from colour import Color

blue, red = Color('blue'), Color('red')
colors = blue.range_to(red, 256)
colors_array = np.array([np.array(color.get_rgb()) * 255 for color in colors])
look_up_table = colors_array.astype(np.uint8)
################## Add #######################

image = pg.ImageItem()
image.setOpts(axisOrder='row-major')  # 2021/01/19 Add
image.setLookupTable(look_up_table)  # Add
image.setImage(data)

ColorLegendItem Create a color bar Add the following:

################## Add #######################
from pgcolorbar.colorlegend import ColorLegendItem

color_bar = ColorLegendItem(imageItem=image, showHistogram=True)
color_bar.resetColorLevels()

window.addItem(color_bar)
################## Add #######################

Pass pg.imgItem to imgeItem. show Histogram can decide whether to display the histogram next to the color bar. The default is True.

Use resetColorLevels () to set the color bar range to the maximum and minimum values ​​of the data.

Executed screen (2021/01/19 before modification) colorbar.png

2021/01/20 postscript

You can set the color bar label with the label argument.

color_bar = ColorLegendItem(imageItem=self.image, showHistogram=True, label='sample')

Overall

Whole code

"""Whole code"""
import sys

from colour import Color
import numpy as np
from pgcolorbar.colorlegend import ColorLegendItem
from PyQt5 import QtWidgets
import pyqtgraph as pg

#Sample array
data = np.random.normal(size=(200, 200))
data[40:80, 40:120] += 4
data = pg.gaussianFilter(data, (15, 15))
data += np.random.normal(size=(200, 200)) * 0.1

app = QtWidgets.QApplication(sys.argv)

window = pg.GraphicsLayoutWidget()

blue, red = Color('blue'), Color('red')
colors = blue.range_to(red, 256)
colors_array = np.array([np.array(color.get_rgb()) * 255 for color in colors])
look_up_table = colors_array.astype(np.uint8)

image = pg.ImageItem()
image.setOpts(axisOrder='row-major')  # 2021/01/19 Add
image.setLookupTable(look_up_table)
image.setImage(data)

view_box = pg.ViewBox()
view_box.setAspectLocked(lock=True)
view_box.addItem(image)

plot = pg.PlotItem(viewBox=view_box)

color_bar = ColorLegendItem(imageItem=image, showHistogram=True, label='sample')  # 2021/01/20 add label
color_bar.resetColorLevels()

window.addItem(plot)
window.addItem(color_bar)

window.show()

sys.exit(app.exec_())

reference

GitHub - titusjan/pgcolorbar: Color bar to use in PyQtGraph plots

Recommended Posts

Create a heatmap with pyqtgraph
Create a homepage with django
Create a directory with python
Create a tweet heatmap with the Google Maps API
Create a 3D model viewer with PyQt5 and PyQtGraph
Draw a graph with Julia + PyQtGraph (2)
Create a virtual environment with Python!
Draw a graph with Julia + PyQtGraph (1)
Draw a graph with Julia + PyQtGraph (3)
Create a poisson stepper with numpy.random
Create a file uploader with Django
Create a Python function decorator with Class
Build a blockchain with Python ① Create a class
Create a dummy image with Python + PIL.
I drew a heatmap with seaborn [Python]
[Python] Create a virtual environment with Anaconda
Let's create a free group with Python
How to create a heatmap with an arbitrary domain in Python
Create a large text file with shellscript
Create a star system with Blender 2.80 script
Create a virtual environment with Python_Mac version
Create a VM with a YAML file (KVM)
Create a simple web app with flask
Create a word frequency counter with Python 3.4
Create a Connecting Nearest Neighbor with NetworkX
Create a web service with Docker + Flask
Create a private repository with AWS CodeArtifact
Create a car meter with raspberry pi
Create a devilish picture with Blender scripts
Create a matrix with PythonGUI (text box)
Draw a graph with PyQtGraph Part 1-Drawing
Create a graph with borders removed with matplotlib
Create a GUI executable file created with tkinter
Create a LINE BOT with Minette for Python
Draw a graph with PyQtGraph Part 3-PlotWidget settings
Create a game UI from scratch with pygame2!
Create a PDF file with a random page size
Create a page that loads infinitely with python
[Note] Create a one-line timezone class with python
You can easily create a GUI with Python
Create a python3 build environment with Sublime Text3
Create a bulletin board with Heroku, Flask, SQLAlchemy
Create a dashboard for Network devices with Django!
Create a matrix with PythonGUI (tkinter combo box)
Create a color bar with Python + Qt (PySide)
Steps to create a Twitter bot with python
Draw a graph with PyQtGraph Part 4-PlotItem settings
Create a decision tree from 0 with Python (1. Overview)
Create a new page in confluence with Python
Create a color-specified widget with Python + Qt (PySide)
How to create a multi-platform app with kivy
Create a one-file hello world application with django
Draw a graph with PyQtGraph Part 6-Displaying a legend
Create a Photoshop format file (.psd) with python
Create a Python console application easily with Click
Create a cylinder with open3d + STL file output
Create a "Hello World" (HTTP) server with Tornado
Create a translation tool with the Translate Toolkit
Create a table of contents with IPython notebook
Create a Django schedule
Create a Python module