2016-09-26 2 views
1

나는 플로팅을 위해 pyqtgraph 라이브러리를 사용합니다. 플롯에서 마우스가 상호 작용하는 것을 정말 좋아합니다 (줌, 팬, ...).pyqtgraph 커스텀 스케일링 문제

내 플롯 중 일부는 마우스 휠을 스크롤 할 때 줌 동작을 변경하고 싶습니다. 표준 구현은 x 방향과 y 방향 모두에서 동시에 확장됩니다. x 방향의 크기 조정은 해당 플롯에서 의미가 없으므로이를 비활성화하고 싶습니다.

################################################################### 
#                 # 
#      PLOTTING A LIVE GRAPH      # 
#     ----------------------------     # 
#                 # 
################################################################### 

import sys 
import os 
from PyQt4 import QtGui 
from PyQt4 import QtCore 
import pyqtgraph as pg 
import numpy as np 

# Override the pg.ViewBox class to add custom 
# implementations to the wheelEvent 
class CustomViewBox(pg.ViewBox): 
    def __init__(self, *args, **kwds): 
     pg.ViewBox.__init__(self, *args, **kwds) 
     #self.setMouseMode(self.RectMode) 


    def wheelEvent(self, ev, axis=None): 
     # 1. Pass on the wheelevent to the superclass, such 
     # that the standard zoomoperation can be executed. 
     pg.ViewBox.wheelEvent(ev,axis) 

     # 2. Reset the x-axis to its original limits 
     # 
     # [code not yet written] 
     # 

class CustomMainWindow(QtGui.QMainWindow): 

    def __init__(self): 

     super(CustomMainWindow, self).__init__() 

     # 1. Define look and feel of this window 
     self.setGeometry(300, 300, 800, 400) 
     self.setWindowTitle("pyqtgraph example") 

     self.FRAME_A = QtGui.QFrame(self) 
     self.FRAME_A.setStyleSheet("QWidget { background-color: %s }" % QtGui.QColor(210,210,235,255).name()) 
     self.LAYOUT_A = QtGui.QHBoxLayout() 
     self.FRAME_A.setLayout(self.LAYOUT_A) 
     self.setCentralWidget(self.FRAME_A) 

     # 2. Create the PlotWidget(QGraphicsView) 
     # ---------------------------------------- 
     self.vb = CustomViewBox() 
     self.plotWidget = pg.PlotWidget(viewBox=self.vb, name='myPlotWidget') 
     self.LAYOUT_A.addWidget(self.plotWidget) 
     self.plotWidget.setLabel('left', 'Value', units='V') 
     self.plotWidget.setLabel('bottom', 'Time', units='s') 
     self.plotWidget.setXRange(0, 10) 
     self.plotWidget.setYRange(0, 100) 

     # 3. Get the PlotItem from the PlotWidget 
     # ---------------------------------------- 
     self.plotItem = self.plotWidget.getPlotItem() 

     # 4. Get the PlotDataItem from the PlotItem 
     # ------------------------------------------ 
     # The plot() function adds a new plot and returns it. 
     # The function can be called on self.plotWidget or self.plotItem 
     self.plotDataItem = self.plotItem.plot() 
     self.plotDataItem.setPen((255, 240, 240)) 
     self.plotDataItem.setShadowPen(pg.mkPen((70, 70, 30), width=2, cosmetic=True)) 


     # 5. Create the x and y arrays 
     # ----------------------------- 
     n = np.linspace(0, 499, 500) 
     self.y = 50 + 5 * (np.sin(n/8.3)) + 7 * (np.sin(n/7.5)) - 5 * (np.sin(n/1.5)) 
     self.x = 10 * n/len(n) 
     self.plotDataItem.setData(x=self.x, y=self.y) 

     self.show() 


if __name__== '__main__': 
    app = QtGui.QApplication(sys.argv) 
    QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Plastique')) 
    myGUI = CustomMainWindow() 


    sys.exit(app.exec_()) 

그냥 신선한 파이썬 파일에이 코드를 복사하여 붙여 넣기하면 다음과 같은 결과가 출력됩니다 얻어야한다 :

enter image description here

불행하게도 오류 메시지가 모든의 mouseWheel에 팝업을 나는 다음 시도 이벤트 :

Traceback (most recent call last): 
    File "pyTest.py", line 26, in wheelEvent 
    pg.ViewBox.wheelEvent(ev,axis) 
    File "C:\Anaconda3\lib\site-packages\pyqtgraph\graphicsItems\ViewBox\ViewBox.py", line 1206, in wheelEvent 
    mask = np.array(self.state['mouseEnabled'], dtype=np.float) 
AttributeError: 'QGraphicsSceneWheelEvent' object has no attribute 'state' 

내 시스템은 다음과 같다 :

  • 파이썬 버전 : 3.5.2
  • PyQt는 버전 : 4.11.4
  • Qt는 버전 : 4.8.7
  • pyqtgraph 버전 : 내의 동료는 내가 가지고있는 지적

답변

1

0.9.10 wheelEvent 기능을 오버라이드 (override) 할 때 첫 번째 인수로 self를 추가합니다 :

# Override the pg.ViewBox class to add custom 
# implementations to the wheelEvent 
class CustomViewBox(pg.ViewBox): 
    def __init__(self, *args, **kwds): 
     pg.ViewBox.__init__(self, *args, **kwds) 
     #self.setMouseMode(self.RectMode) 


    def wheelEvent(self, ev, axis=None): 
     print(str(self.viewRange())) 

     # 1. Pass on the wheelevent to the superclass, such 
     # that the standard zoomoperation can be executed. 
     pg.ViewBox.wheelEvent(self,ev,axis) # <- To override the function 
               properly, one should add 
               'self' as first argument 

     # 2. Reset the x-axis to its original limits 
     self.setXRange(0,10) 

이 지금은 작동합니다. -

def wheelEvent(self, ev, axis=None): 
    # 1. Determine initial x-range 
    initialRange = self.viewRange() 

    # 2. Call the superclass method for zooming in 
    pg.ViewBox.wheelEvent(self,ev,axis) 

    # 3. Reset the x-axis to its original limits 
    self.setXRange(initialRange[0][0],initialRange[0][1]) 

문제는 기능 self.viewRange()가 [0,10]하지만를 [반환하지 않는다는 것입니다 :

# 2. Reset the x-axis to its original limits 
    self.setXRange(0,10) 

이렇게 좋을 것입니다 :하지만 유일한 단점은 다음 코드 행은 0.37, 10.37] 대신에. viewBox는 왼쪽과 오른쪽에 약간의 여백을 추가합니다. 그렇게하면 계속 마진이 시간에 따라 변합니다. [-0.37, 10.37] -> [-0.74, 10.74] -> ...