~kenneth-arnold/svdview/pyqt-junk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import sys
from PyQt4.QtCore import Qt, QRectF as Rect, QPointF as Point, QLineF as Line
from PyQt4.QtGui import (QApplication, QGraphicsScene, QGraphicsView,
                         QColor, QGraphicsItem, QGraphicsEllipseItem,
                         QGraphicsPixmapItem, QPixmap, QGraphicsWidget,
                         QImage)
import numpy as np
from itertools import izip
from csc.util.persist import load_pickle
from csc.divisi.tensor import data, DenseTensor
from csc.divisi.labeled_view import LabeledView

# This initializes Qt, and nothing works without it. Even though we
# don't use the "app" variable until the end.
app = QApplication(sys.argv)

class QImageWidget(QGraphicsWidget):
    def __init__(self, image):
        '''
        A QGraphicsItem that draws a QImage.
        '''
        super(QImageWidget, self).__init__()
        self.image = image
        
    def paint(self, painter, option, widget):
        painter.drawImage(0, 0, self.image)


#class SVDPixmap(QGraphicsPixmapItem):

class SVDScene(QGraphicsScene):
    def __init__(self, positions, connections):
        QGraphicsScene.__init__(self)
        self.setBackgroundBrush(QColor(50, 50, 50))
        
        # store data from the input matrix
        self.positions = positions
        self.connections = connections
        self.nitems, self.ndim = positions.shape
        self.array = data(positions)
        self.labels = positions.label_list(0)

        self.pixels = np.zeros((400, 400, 4), dtype=np.uint8)
        self.background_image = QImage(self.pixels, 400, 400, QImage.Format_RGB32)

        # calculate the matrix that projects N-D to 2-D
        self.proj_matrix = np.zeros((self.array.shape[1], 2))
        for idx in (0, 1):
            self.proj_matrix[idx, idx] = 1

        # draw points
        self.locs = np.dot(self.array, self.proj_matrix)
#         self.points = []
#         for idx in xrange(len(self.locs)):
#             x, y = self.locs[idx]
#             colors = self.array[idx, 0:3]
#             colorvec = np.clip(colors*5000+128, 0, 255)
#             pen = QColor(*colorvec)
#             brush = QColor(*colorvec)
#             point = SVDPoint(x, y, .001, pen, brush)
#             self.points.append(point)
#             self.addItem(point)
        
        xsize = np.max(self.locs[:,0]) - np.min(self.locs[:,0])
        ysize = np.max(self.locs[:,1]) - np.min(self.locs[:,1])
        size = max(xsize, ysize)
        self.bounding_rect = Rect(np.min(self.locs[:,0]), np.min(self.locs[:,1]), size, size)
        
        self.setSceneRect(self.bounding_rect)
        self.setItemIndexMethod(QGraphicsScene.NoIndex)
        #self.setSortCacheEnabled(False)

    def drawBackground(self, painter, revealed_rect):
        #painter.fillRect(revealed_rect, self.backgroundBrush())
        point_color = QColor(255, 0, 0)
        pixels = self.pixels
        pixels[:, :, :] = (50, 50, 50, 0)
        for x, y in self.locs:
            pixels[200, 200, :] = (255, 0, 0, 0)
        painter.drawImage(0, 0, self.background_image)

    def mouseMoveEvent(self, mouseEvent):
        point = mouseEvent.screenPos()
        angle = point.x() / 200
        self.proj_matrix[0,:] = [np.cos(angle), np.sin(angle)]
        self.update_projection()

    def update_projection(self):
        self.locs = np.dot(self.array, self.proj_matrix)
        self.invalidate(self.sceneRect())

    def screenX(self, x):
        '''
        Convert points from projection coordinates to screen coordinates.
        '''
        return (x-screenLeft) / (screenRight-screenLeft) * width
    

class SVDView(QGraphicsView):
    def __init__(self, projection):
        QGraphicsView.__init__(self, projection)
        self.projection = projection   # same as self.scene()
        print self.sceneRect()
        self.fitInView(self.sceneRect(), Qt.KeepAspectRatio)

def main():
    cnet = load_pickle('cnet.pickle')
    svd = cnet.normalized().svd()
    proj = SVDScene(svd.u, cnet)
    view = SVDView(proj)
    view.setGeometry(300, 300, 600, 600)
    view.setWindowTitle("SVDview")
    view.show()
    app.exec_()

if __name__ == '__main__': main()