📄 ownomogramgraph.py
字号:
a.setX(min_mapped-5)
a.setY(mapped_labels[at]-canvas.fontSize/2)
if attLineLabel.attValues[at].enable:
a.marker.setPoints(min_mapped-2, mapped_labels[at], min_mapped+2, mapped_labels[at])
a.show()
# if value is disabled, draw just a symbolic line
else:
a.marker.setPoints(min_mapped-1, mapped_labels[at], min_mapped+1, mapped_labels[at])
a.marker.show()
#finds proportionally where zero value is
def findZeroValue(self):
maxPos,zero = 1,0
while self.attValues[maxPos].betaValue!=0 and self.attValues[maxPos-1].betaValue!=0 and self.attValues[maxPos].betaValue/abs(self.attValues[maxPos].betaValue) == self.attValues[maxPos-1].betaValue/abs(self.attValues[maxPos-1].betaValue):
maxPos+=1
if maxPos == len(self.attValues):
maxPos-=1
zero = self.attValues[maxPos].betaValue
break
if not self.attValues[maxPos].betaValue == self.attValues[maxPos-1].betaValue:
return ((zero-self.attValues[maxPos-1].betaValue)/(self.attValues[maxPos].betaValue - self.attValues[maxPos-1].betaValue),maxPos,zero)
else:
return (zero,maxPos,zero)
# string representation of attribute
def toString(self):
return self.name + str([at.toString() for at in self.attValues])
# ####################################################################
# Continuous attribute in 2d
# ####################################################################
class AttrLineCont(AttrLine):
def __init__(self, name, canvas):
AttrLine.__init__(self, name, canvas)
# continuous attributes
self.cAtt = None
self.box = QCanvasRectangle(canvas)
self.box.setPen(QPen(Qt.DotLine))
self.contValues = []
self.contLabel = []
def getHeight(self, canvas):
if canvas.parent.contType == 1:
return canvas.parent.verticalSpacingContinuous
return AttrLine.getHeight(self, canvas)
# initialization before 2d paint
def initializeBeforePaint(self, canvas):
self.atNames = AttrLine(self.name, canvas)
for at in self.attValues:
self.atNames.addAttValue(AttValue(at.name, float(at.name)))
verticalRect = QRect(0, 0, self.getHeight(canvas), self.getHeight(canvas))
verticalMapper = Mapper_Linear_Fixed(self.atNames.minValue, self.atNames.maxValue, verticalRect.left()+verticalRect.width()/4, verticalRect.right(), maxLinearValue = self.atNames.maxValue, minLinearValue = self.atNames.minValue)
label = verticalMapper.getHeaderLine(canvas, QRect(0,0,self.getHeight(canvas), self.getHeight(canvas)))
[l.setCanvas(None) for l in self.contLabel]
self.contLabel=[]
for val in label.attValues:
# draw value
a = QCanvasText(val.name, canvas)
a.setTextFlags(Qt.AlignRight)
a.marker = QCanvasLine(canvas)
a.marker.setZ(5)
self.contLabel.append(a)
#line objects
if len(self.contValues) == 0:
for at in self.attValues:
a = QCanvasLine(canvas)
a.upperSE = QCanvasLine(canvas)
a.lowerSE = QCanvasLine(canvas)
a.setPen(QPen(Qt.black, at.lineWidth))
a.upperSE.setPen(QPen(Qt.blue, 0))
a.lowerSE.setPen(QPen(Qt.blue, 0))
self.contValues.append(a)
# for 1d cont space
at.setCreation(canvas)
def paint(self, canvas, rect, mapper):
self.label.setText(self.name)
atValues_mapped, atErrors_mapped, min_mapped, max_mapped = mapper(self, error_factor = norm_factor(1-((1-float(canvas.parent.confidence_percent)/100.)/2.))) # return mapped values, errors, min, max --> mapper(self)
self.drawAttributeLine(canvas, rect, mapper)
# continuous attributes are handled differently
self.cAtt = self.shrinkSize(canvas, rect, mapper)
atValues_mapped, atErrors_mapped, min_mapped, max_mapped = mapper(self.cAtt) # return mapped values, errors, min, max --> mapper(self)
val = self.cAtt.attValues
for i in range(len(val)):
# check attribute name that will not cover another name
val[i].x = atValues_mapped[i]
val[i].paint(canvas, rect, mapper)
for j in range(i):
if val[j].over==val[i].over and val[j].enable and val[i].text.collidesWith(val[j].text):
val[i].enable = False
if not val[i].enable:
val[i].paint(canvas, rect, mapper)
self.selectValues.append([atValues_mapped[i], rect.bottom(), val[i].betaValue])
atLine = AttrLine("marker", canvas)
d = 5*(self.cAtt.maxValue-self.cAtt.minValue)/max(max_mapped-min_mapped,aproxZero)
for xc in Numeric.arange(self.cAtt.minValue, self.cAtt.maxValue+d, d):
atLine.addAttValue(AttValue("", xc))
markers_mapped, mark_errors_mapped, markMin_mapped, markMax_mapped = mapper(atLine)
for mar in range(len(markers_mapped)):
xVal = markers_mapped[mar]
if filter(lambda x: abs(x[0]-xVal)<4, self.selectValues) == [] and xVal<max_mapped:
self.selectValues.append([xVal, rect.bottom(), atLine.attValues[mar].betaValue])
self.updateValue()
self.line.show()
self.label.show()
# create an AttrLine object from a continuous variable (to many values for a efficient presentation)
def shrinkSize(self, canvas, rect, mapper):
# get monotone subset of this continuous variable
monotone_subsets, curr_subset = [],[]
sign=1
for at_i in range(len(self.attValues)):
if at_i<len(self.attValues)-1 and sign*(self.attValues[at_i].betaValue-self.attValues[at_i+1].betaValue)>0:
curr_subset.append(self.attValues[at_i])
monotone_subsets.append(curr_subset)
curr_subset = [self.attValues[at_i]]
sign=-sign
else:
curr_subset.append(self.attValues[at_i])
monotone_subsets.append(curr_subset)
# create retAttr --> values in between can be easily calculated from first left and first right
retAttr = AttrLine(self.name, canvas)
for at in self.attValues:
if at.betaValue == self.minValue or at.betaValue == self.maxValue:
at.enable = True
retAttr.addAttValue(at)
curr_over = False
# convert monotone subsets to nice step-presentation
for m in monotone_subsets:
if len(m)<2:
continue
curr_over = not curr_over
maxValue = max(float(m[0].name), float(m[len(m)-1].name))
minValue = min(float(m[0].name), float(m[len(m)-1].name))
width = mapper.mapBeta(max(m[0].betaValue, m[len(m)-1].betaValue),self) - mapper.mapBeta(min(m[0].betaValue, m[len(m)-1].betaValue),self)
curr_rect = QRect(rect.left(), rect.top(), width, rect.height())
mapperCurr = Mapper_Linear_Fixed(minValue, maxValue, curr_rect.left(), curr_rect.right(), maxLinearValue = maxValue, minLinearValue = minValue)
label = mapperCurr.getHeaderLine(canvas, curr_rect)
for at in label.attValues:
if at.betaValue>=minValue and at.betaValue<=maxValue:
for i in range(len(m)):
if i<(len(m)-1):
if float(m[i].name)<=at.betaValue and float(m[i+1].name)>=at.betaValue:
coeff = (at.betaValue-float(m[i].name))/max(float(m[i+1].name)-float(m[i].name),aproxZero)
retAttr.addAttValue(AttValue(str(at.betaValue),m[i].betaValue+coeff*(m[i+1].betaValue-m[i].betaValue)))
retAttr.attValues[len(retAttr.attValues)-1].over = curr_over
return retAttr
def paint2d(self, canvas, rect, mapper):
self.initializeBeforePaint(canvas)
self.label.setText(self.name)
# get all values tranfsormed with current mapper
atValues_mapped, atErrors_mapped, min_mapped, max_mapped = mapper(self, error_factor = norm_factor(1-((1-float(canvas.parent.confidence_percent)/100.)/2.))) # return mapped values, errors, min, max --> mapper(self)
# draw a bounding box
self.drawBox(min_mapped, max_mapped, rect)
#draw legend from real values
verticalRect = QRect(rect.top(), rect.left(), rect.height(), rect.width())
verticalMapper = Mapper_Linear_Fixed(self.atNames.minValue, self.atNames.maxValue, verticalRect.left()+verticalRect.width()/4, verticalRect.right(), maxLinearValue = self.atNames.maxValue, minLinearValue = self.atNames.minValue, inverse=True)
label = verticalMapper.getHeaderLine(canvas, verticalRect)
mapped_labels, error, min_lab, max_lab = verticalMapper(label) # return mapped values, errors, min, max --> mapper(self)
self.drawVerticalLabel(label, min_mapped, mapped_labels, canvas)
#create a vertical mapper
atValues_mapped_vertical, atErrors_mapped_vertical, min_mapped_vertical, max_mapped_vertical = verticalMapper(self.atNames) # return mapped values, errors, min, max --> mapper(self)
#find and select zero value (beta = 0)
(propBeta,maxPos,zero) = self.findZeroValue()
zeroValue = float(self.attValues[maxPos-1].name) + propBeta*(float(self.attValues[maxPos].name) - float(self.attValues[maxPos-1].name))
self.selectValues = [[mapper.mapBeta(zero, self),verticalMapper.mapBeta(zeroValue, self.atNames), zero, zeroValue]]
if not self.selectedValue:
self.selectedValue = self.selectValues[0]
# draw lines
for i in range(len(atValues_mapped)-1):
a = self.contValues[i]
if canvas.parent.histogram:
a.setPen(QPen(Qt.black, 1+self.attValues[i].lineWidth*canvas.parent.histogram_size))
else:
a.setPen(QPen(Qt.black, 2))
#if self.attValues[i].lineWidth>0:
a.setPoints(atValues_mapped[i], atValues_mapped_vertical[i], atValues_mapped[i+1], atValues_mapped_vertical[i+1])
a.upperSE.setPoints(atErrors_mapped[i][0], atValues_mapped_vertical[i], atErrors_mapped[i+1][0], atValues_mapped_vertical[i+1])
a.lowerSE.setPoints(atErrors_mapped[i][1], atValues_mapped_vertical[i], atErrors_mapped[i+1][1], atValues_mapped_vertical[i+1])
self.selectValues.append([atValues_mapped[i],atValues_mapped_vertical[i], self.attValues[i].betaValue, self.atNames.attValues[i].betaValue])
# if distance between i and i+1 is large, add some select values.
n = int(math.sqrt(math.pow(atValues_mapped[i+1]-atValues_mapped[i],2)+math.pow(atValues_mapped_vertical[i+1]-atValues_mapped_vertical[i],2)))/5-1
self.selectValues = self.selectValues + [[atValues_mapped[i]+(float(j+1)/float(n+1))*(atValues_mapped[i+1]-atValues_mapped[i]),
atValues_mapped_vertical[i]+(float(j+1)/float(n+1))*(atValues_mapped_vertical[i+1]-atValues_mapped_vertical[i]),
self.attValues[i].betaValue+(float(j+1)/float(n+1))*(self.attValues[i+1].betaValue-self.attValues[i].betaValue),
self.atNames.attValues[i].betaValue+(float(j+1)/float(n+1))*(self.atNames.attValues[i+1].betaValue-self.atNames.attValues[i].betaValue)] for j in range(n)]
a.show()
if canvas.parent.confidence_check:
a.upperSE.show()
a.lowerSE.show()
else:
a.upperSE.hide()
a.lowerSE.hide()
self.updateValue()
self.box.show()
self.label.show()
# ####################################################################
# Ordered attribute in 2d
# ####################################################################
class AttrLineOrdered(AttrLine):
def __init__(self, name, canvas):
AttrLine.__init__(self, name, canvas)
# continuous attributes
self.box = QCanvasRectangle(canvas)
self.box.setPen(QPen(Qt.DotLine))
self.contValues = []
self.contLabel = []
def getHeight(self, canvas):
if canvas.parent.contType == 1:
return len(self.attValues)*canvas.parent.diff_between_ordinal+canvas.parent.diff_between_ordinal
return AttrLine.getHeight(self, canvas)
# initialization before 2d paint
def initializeBeforePaint(self, canvas):
[l.setCanvas(None) for l in self.contLabel]
self.contLabel=[]
for val in self.attValues:
# draw value
a = QCanvasText(val.name, canvas)
a.setTextFlags(Qt.AlignRight)
a.marker = QCanvasLine(canvas)
a.marker.setZ(5)
self.contLabel.append(a)
#line objects
if len(self.contValues) == 0:
for at in self.attValues:
a = QCanvasLine(canvas)
a.setPen(QPen(Qt.black, at.lineWidth))
self.contValues.append(a)
# for 1d cont space
at.setCreation(canvas)
def getVerticalCoordinates(self, rect, val):
return rect.bottom() - val.verticalDistance
def paint2d_fixedDistance(self, canvas, rect, mapper):
d = canvas.parent.diff_between_ordinal/2
for at in self.attValues:
at.verticalDistance = d
d += canvas.parent.diff_between_ordinal
# get all values tranfsormed with current mapper
atValues_mapped, atErrors_mapped, min_mapped, max_mapped = mapper(self) # return mapped values, errors, min, max --> mapper(self)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -