PyQtGraphで複数のy軸を描く（DockArea編）

# これは何？

複数のY軸をDockエリアのグラフに描画するコードです。
完成図は、以下のとおりです。

![image.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191337/12b59b47-a6f1-7e1e-2483-b7bb67aefa13.jpeg)

PyQtGraphを使用しています。


# 環境

- Darwin monju.local 21.1.0 Darwin Kernel Version 21.1.0: Wed Oct 13 17:33:23 PDT 2021; root:xnu-8019.41.5~1/RELEASE_X86_64 x86_64
- Python 3.9.1
- MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports)



# コードはこちら


PySide6用とPyQt5用のコードを記載しています。
説明は特に不要かと思います。


DockAreaのラベル？は、デフォルトで紫色なのですが、以下のサイトを参考にしてグレーに変更しております。
ありがとうございます。

http://fatbald.seesaa.net/article/451667700.html


<details><summary>multiple_y_dock.py</summary><div>

```python
'''
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import uic
import pyqtgraph as pg
from pyqtgraph.dockarea import *

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi('simple_dock_plot.ui', self)

'''
import sys
from PySide6 import QtWidgets
from PySide6.QtGui import QFont
from PySide6.QtWidgets import QApplication
from simple_dock_plot import Ui_MainWindow

import pyqtgraph as pg
from pyqtgraph.dockarea import *

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    '''初期化メソッド（インスタンス変数の定義）'''
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi(self) # この中で必要なMainWindowの定数が宣言

        '''
        ここからPyQt5とPySide6と共通
        '''
        self.d1 = Dock('Multiple Y-axis')

        self.setWindowTitle('pyqtgraph example: MultiplePlotAxes')
        self.plot()
        self.updateViews()
        self.p1.plotItem.vb.sigResized.connect(self.updateViews)

    def plot(self):
        # Dockの準備
        self.graphicsView.addDock(self.d1)

        # Dockに表示するPlotWidgetをインスタンス化
        self.p1 = pg.PlotWidget()
        ## create a new ViewBox, link the right axis to its coordinate system
        self.p2 = pg.ViewBox()
        # scene(p2)用の軸を右側に設定
        self.p1.scene().addItem(self.p2)
        self.p1.showAxis('right')
        # 以下の行にて右側の軸がp2に連動するように指定
        # 指定しないと左側の軸と右側の軸が同じになる
        self.p1.getAxis('right').linkToView(self.p2)
        
        # p1とp2のx軸を連動させる場合は指定
        self.p2.setXLink(self.p1)
        self.setFont(QFont('Noto Sans Mono Regular'))
        
        # 軸の名称を指定
        # font-familyは、Font Bookに記載されている正式名称を設定、スペースがあっても構いません
        fontCss = {'font-family': "Arial, Noto Sans Mono Regular", 'font-size': '24pt'}
        fontCss["color"] = '#fff' 
        self.p1.getAxis('bottom').setLabel(**fontCss)
        self.p1.setLabels(bottom='X軸')

        fontCss["color"] = '#f0f' 
        self.p1.getAxis('right').setLabel(**fontCss)
        self.p1.setLabels(right='こちらはY2軸！')

        fontCss["color"] = '#ff0' 
        self.p1.getAxis('left').setLabel(**fontCss)
        self.p1.setLabels(left='こちらY1軸です')


        x1=[1,2,3,4,5,6]
        y1 = [1,2,4,8,16,32]
        y2 = [10,20,40,80,40,20]

        # グラフを描画
        self.p1.plot(x=x1, y=y1, pen='#ff0')
        self.p2.addItem(pg.PlotCurveItem(x=x1, y=y2, pen='#f0f'))

        # dockWidgetにp1を追加
        self.d1.addWidget(self.p1)

    ## Handle view resizing
    def updateViews(self):
        ## view has resized; update auxiliary views to match
        self.p2.setGeometry(self.p1.plotItem.vb.sceneBoundingRect())
        ## need to re-update linked axes since this was called
        ## incorrectly while views had different shapes.
        ## (probably this should be handled in ViewBox.resizeEvent)
        self.p2.linkedViewChanged(self.p1.plotItem.vb, self.p2.XAxis)


def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec()


if __name__ == '__main__':
    from pyqtgraph.dockarea.Dock import DockLabel
    def updateStyle(self):
        self.setStyleSheet("DockLabel { color: #FFF; background-color: #444; font-size:20pt}")
    setattr(DockLabel, 'updateStyle', updateStyle)
    
    style = """
        QWidget { color: #AAA; background-color: #333; border: 0px; padding: 0px; }
        QWidget:item:selected { background-color: #666; }
        QMenuBar::item { background: transparent; }
        QMenuBar::item:selected { background: transparent; border: 1px solid #666; }
    """
    main()
```
</div></details>



<details><summary>simple_dock_plot.py</summary><div>

```python

# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'simple_dock_plot.ui'
##
## Created by: Qt User Interface Compiler version 6.2.1
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout, QMainWindow,
    QMenuBar, QPushButton, QSizePolicy, QSpacerItem,
    QSplitter, QStatusBar, QWidget)

from pyqtgraph.dockarea import DockArea

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(640, 480)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName(u"gridLayout")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)

        self.horizontalLayout.addItem(self.horizontalSpacer)

        self.pushButton = QPushButton(self.centralwidget)
        self.pushButton.setObjectName(u"pushButton")

        self.horizontalLayout.addWidget(self.pushButton)


        self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1)

        self.horizontalLayout_2 = QHBoxLayout()
        self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
        self.graphicsView = DockArea(self.centralwidget)
        self.graphicsView.setObjectName(u"graphicsView")
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.graphicsView.sizePolicy().hasHeightForWidth())
        self.graphicsView.setSizePolicy(sizePolicy)
        self.graphicsView.setMinimumSize(QSize(0, 0))

        self.horizontalLayout_2.addWidget(self.graphicsView)

        self.splitter = QSplitter(self.centralwidget)
        self.splitter.setObjectName(u"splitter")
        self.splitter.setOrientation(Qt.Vertical)

        self.horizontalLayout_2.addWidget(self.splitter)


        self.gridLayout.addLayout(self.horizontalLayout_2, 0, 0, 1, 1)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 1043, 21))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.pushButton.clicked.connect(MainWindow.close)

        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
        self.pushButton.setText(QCoreApplication.translate("MainWindow", u"Quit", None))
    # retranslateUi

```
</div></details>


<details><summary>simple_dock_plot.ui</summary><div>

```xml

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>640</width>
    <height>480</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="1" column="0">
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QPushButton" name="pushButton">
        <property name="text">
         <string>Quit</string>
       </property>
       </widget>
      </item>
     </layout>
    </item>
    <item row="0" column="0">
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <widget class="DockArea" name="graphicsView">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="minimumSize">
         <size>
          <width>0</width>
          <height>0</height>
         </size>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QSplitter" name="splitter">
        <property name="orientation">
         <enum>Qt::Vertical</enum>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1043</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
  <customwidget>
   <class>DockArea</class>
   <extends>QGraphicsView</extends>
   <header>pyqtgraph.dockarea</header>
  </customwidget>
</customwidgets>
<resources/>
<connections>
  <connection>
   <sender>pushButton</sender>
   <signal>clicked()</signal>
   <receiver>MainWindow</receiver>
   <slot>close()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>756</x>
     <y>551</y>
    </hint>
    <hint type="destinationlabel">
     <x>615</x>
     <y>550</y>
    </hint>
   </hints>
  </connection>
</connections>
</ui>

```
</div></details>