我已经有了这个非常基本的绘图代码,基于如何在 QGraphicsView 中绘制折线(“开放多边形”),但我不明白为什么绘图没有出现在左上角。我想:
scene = QGraphicsScene(0,0, self.width, self.height) #/10443894/
应该够了。但这似乎不起作用。有人可以指出我需要改变什么才能使情节到达正确的位置。 非常感谢。
#!/usr/bin/python3
#
from PyQt5.QtGui import QColor, QFont, QPainter, QPainterPath, QPainterPathStroker, QPen, QPolygonF ####NEW
from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtWidgets import QApplication, QGraphicsScene, QGraphicsPathItem, QGraphicsView, QMainWindow
import sys
class plot(QMainWindow):
#
def plot_parameters(self, data, width, height):
len_data = len(data)
# pixel_ratio changes the raw data x-value to a screen x-value
pixel_ratio_x = width/len_data # transform ratio for x-axis
min_y = min(data)
max_y = max(data)
# pixel_ratio changes the raw data y-value to a screen y-value
pixel_ratio_y = height/(max_y-min_y)
return pixel_ratio_x, pixel_ratio_y, min_y, max_y, len_data
#
def y_axis_data(self, min_y, max_y):
# Y labels - a plotdata must be >= 0 - TODO
y_labels = [max_y]
yl_increment='1' # label increment
lenlblvalue=len(str(int(min_y))) # label length
if min_y>0.0:
lenlblvalue=len(str(int(max_y)))
min_y=0.0
yunit=len(str(max(int(max_y), abs(int(min_y)))))-1 # maximum units of y values
for i in range(0, yunit): # create increment
yl_increment+='0'
lblvalue=int((int(str(max_y)[0])+1)*int(yl_increment))# first lblvalue
yl_increment=int(yl_increment)*.25
while lblvalue>=max_y:
lblvalue-=yl_increment
while (lblvalue>min_y and lblvalue<max_y): #draw value labels and lines
lblvalue -= yl_increment
y_labels.append(lblvalue)
# y axis line tick marks
return y_labels,yl_increment
def plot_decoration(self, scene, data, min_y, max_y, width, height):
# create a y-axis with tick marks, labels and lines
pen = QPen(Qt.gray, 0.5)
# calculate the y-axis line positions
y_labels,yl_increment = self.y_axis_data(min_y, max_y)
# initial line position on y-axis
y_position = 0
# add a tick mark and label at y_position
for l in list(y_labels):
y_position = l
line = scene.addLine(0,height-(y_position*self.pixel_ratio_y), width, height-(y_position*self.pixel_ratio_y))
line.setPen(pen)
txt = scene.addText(str(l), QFont('sans',8,QFont.Light)) #/27612052/
txt.setPos(0,height-(y_position*self.pixel_ratio_y)-12) # -12 to line up with tick mark
y_position += yl_increment # move to next position
#
def create_plot(self):
self.width = 700
self.height = 400
poly_plot_data = []
# create scene and view
scene = QGraphicsScene(0,0, self.width, self.height) #/10443894/
view = QGraphicsView(scene)
view.show()
# raw data
data = [-10, -12, 0, -5, -10, -20]
# get parameters of data for plotting
self.pixel_ratio_x, self.pixel_ratio_y, min_y, max_y, len_data = self.plot_parameters(data, self.width, self.height)
# create polyline data
for d in range(0, len_data):
poly_plot_data.append(QPointF(int(d*self.pixel_ratio_x), ((self.height)-(data[d])*self.pixel_ratio_y)))
# draw the axes - TODO x-axis
self.plot_decoration(scene, data, min_y, max_y, self.width, self.height)
# draw polyline
poly = QPolygonF(poly_plot_data) # /68704191/
path = QPainterPath()
path.addPolygon(poly)
new_item = QGraphicsPathItem(path, None)
new_item.setPen(QPen(QColor("red"), 1))
scene.addItem(new_item)
return view
#
def __init__(self):
super().__init__()
plot = self.create_plot()
self.setCentralWidget(plot)
self.show()
###########################################
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = plot()
sys.exit(app.exec_())
这不是 PyQt 问题,这是图形缩放问题。
您需要在计算中考虑最小 y 值 从数据范围转换为图表的显示范围 正在画画。您正在绘制的数据的 y 值在 -20 到 0 的范围内。最重要的是,最小 y 值不为零。
这是计算要添加到
poly_plot_data
的点的循环,为了清晰起见,进行了格式化:
for d in range(0, len_data):
poly_plot_data.append(QPointF(
int(d*self.pixel_ratio_x), ((self.height)-(data[d])*self.pixel_ratio_y)))
数据中的最小 y 值为 -20,其中
self.height
为 400,self.pixel_ratio_y
为 20。如果 data[d]
为 -20
,则
((self.height)-(data[d])*self.pixel_ratio_y)
计算为 400-(-20)*20
,等于 800,这显然不在 0 到 400 的范围内。
如果您希望图形场景中数据中的最小 y 值缩放为 y = 400,则需要在乘以比例因子之前从每个数据点中减去最小 y 值:
for d in range(0, len_data):
poly_plot_data.append(QPointF(
int(d*self.pixel_ratio_x), ((self.height)-(data[d]-min_y)*self.pixel_ratio_y)))
data[d]-min_y
是您的数据点比最小值多远,然后我们按像素比缩放,并从 400 中减去以确保 0 位于底部,400 位于顶部。
您还需要更改在图表上绘制刻度标签和线条的代码以减去
min_y
。我将由您来进行这些更改。