#!/usr/bin/env python
# The Python version of qwt-5.0/examples/histogram
import random
import sys
from PyQt4 import Qt
import PyQt4.Qwt5 as Qwt
class HistogramItem(Qwt.QwtPlotItem):
Auto = 0
Xfy = 1
def __init__(self, *args):
Qwt.QwtPlotItem.__init__(self, *args)
self.__attributes = HistogramItem.Auto
self.__data = Qwt.QwtIntervalData()
self.__color = Qt.QColor()
self.__reference = 0.0
self.setItemAttribute(Qwt.QwtPlotItem.AutoScale, True)
self.setItemAttribute(Qwt.QwtPlotItem.Legend, True)
self.setZ(20.0)
# __init__()
def setData(self, data):
self.__data = data
self.itemChanged()
# setData()
def data(self):
return self.__data
# data()
def setColor(self, color):
if self.__color != color:
self.__color = color
self.itemChanged()
# setColor()
def color(self):
return self.__color
# color()
def boundingRect(self):
result = self.__data.boundingRect()
if not result.isvalid():
return result
if self.testHistogramAttribute(HistogramItem.Xfy):
result = Qwt.QwtDoubleRect(result.y(), result.x(),
result.height(), result.width())
if result.left() > self.baseline():
result.setLeft(self.baseline())
elif result.right() < self.baseline():
result.setRight(self.baseline())
else:
if result.bottom() < self.baseline():
result.setBottom(self.baseline())
elif result.top() > self.baseline():
result.setTop(self.baseline())
return result
# boundingRect()
def rtti(self):
return Qwt.QwtPlotItem.PlotHistogram
# rtti()
def draw(self, painter, xMap, yMap, rect):
iData = self.data()
painter.setPen(self.color())
x0 = xMap.transform(self.baseline())
y0 = yMap.transform(self.baseline())
for i in range(iData.size()):
if self.testHistogramAttribute(HistogramItem.Xfy):
x2 = xMap.transform(iData.value(i))
if x2 == x0:
continue
y1 = yMap.transform(iData.interval(i).minValue())
y2 = yMap.transform(iData.interval(i).maxValue())
if y1 > y2:
y1, y2 = y2, y1
if i < iData.size()-2:
yy1 = yMap.transform(iData.interval(i+1).minValue())
yy2 = yMap.transform(iData.interval(i+1).maxValue())
if y2 == min(yy1, yy2):
xx2 = xMap.transform(iData.interval(i+1).minValue())
if xx2 != x0 and ((xx2 < x0 and x2 < x0)
or (xx2 > x0 and x2 > x0)):
# One pixel distance between neighboured bars
y2 += 1
self.drawBar(
painter, Qt.Qt.Horizontal, Qt.QRect(x0, y1, x2-x0, y2-y1))
else:
y2 = yMap.transform(iData.value(i))
if y2 == y0:
continue
x1 = xMap.transform(iData.interval(i).minValue())
x2 = xMap.transform(iData.interval(i).maxValue())
if x1 > x2:
x1, x2 = x2, x1
if i < iData.size()-2:
xx1 = xMap.transform(iData.interval(i+1).minValue())
xx2 = xMap.transform(iData.interval(i+1).maxValue())
x2 = min(xx1, xx2)
yy2 = yMap.transform(iData.value(i+1))
if x2 == min(xx1, xx2):
if yy2 != 0 and (( yy2 < y0 and y2 < y0)
or (yy2 > y0 and y2 > y0)):
# One pixel distance between neighboured bars
x2 -= 1
self.drawBar(
painter, Qt.Qt.Vertical, Qt.QRect(x1, y0, x2-x1, y2-y0))
# draw()
def setBaseline(self, reference):
if self.baseline() != reference:
self.__reference = reference
self.itemChanged()
# setBaseLine()
def baseline(self,):
return self.__reference
# baseline()
def setHistogramAttribute(self, attribute, on = True):
if self.testHistogramAttribute(attribute):
return
if on:
self.__attributes |= attribute
else:
self.__attributes &= ~attribute
self.itemChanged()
# setHistogramAttribute()
def testHistogramAttribute(self, attribute):
return bool(self.__attributes & attribute)
# testHistogramAttribute()
def drawBar(self, painter, orientation, rect):
painter.save()
color = painter.pen().color()
r = rect.normalized()
factor = 125;
light = color.light(factor)
dark = color.dark(factor)
painter.setBrush(color)
painter.setPen(Qt.Qt.NoPen)
Qwt.QwtPainter.drawRect(painter, r.x()+1, r.y()+1,
r.width()-2, r.height()-2)
painter.setBrush(Qt.Qt.NoBrush)
painter.setPen(Qt.QPen(light, 2))
Qwt.QwtPainter.drawLine(
painter, r.left()+1, r.top()+2, r.right()+1, r.top()+2)
painter.setPen(Qt.QPen(dark, 2))
Qwt.QwtPainter.drawLine(
painter, r.left()+1, r.bottom(), r.right()+1, r.bottom())
painter.setPen(Qt.QPen(light, 1))
Qwt.QwtPainter.drawLine(
painter, r.left(), r.top() + 1, r.left(), r.bottom())
Qwt.QwtPainter.drawLine(
painter, r.left()+1, r.top()+2, r.left()+1, r.bottom()-1)
painter.setPen(Qt.QPen(dark, 1))
Qwt.QwtPainter.drawLine(
painter, r.right()+1, r.top()+1, r.right()+1, r.bottom())
Qwt.QwtPainter.drawLine(
painter, r.right(), r.top()+2, r.right(), r.bottom()-1)
painter.restore()
# drawBar()
# class HistogramItem
def make():
demo = Qwt.QwtPlot()
demo.setCanvasBackground(Qt.Qt.white)
demo.setTitle("Histogram")
grid = Qwt.QwtPlotGrid()
grid.enableXMin(True)
grid.enableYMin(True)
grid.setMajPen(Qt.QPen(Qt.Qt.black, 0, Qt.Qt.DotLine));
grid.setMinPen(Qt.QPen(Qt.Qt.gray, 0 , Qt.Qt.DotLine));
grid.attach(demo)
histogram = HistogramItem()
histogram.setColor(Qt.Qt.darkCyan)
numValues = 20
intervals = []
values = Qwt.QwtArrayDouble(numValues)
pos = 0.0
for i in range(numValues):
width = 5 + random.randint(0, 4)
value = random.randint(0, 99)
intervals.append(Qwt.QwtDoubleInterval(pos, pos+width));
values[i] = value
pos += width
histogram.setData(Qwt.QwtIntervalData(intervals, values))
histogram.attach(demo)
demo.setAxisScale(Qwt.QwtPlot.yLeft, 0.0, 100.0)
demo.setAxisScale(Qwt.QwtPlot.xBottom, 0.0, pos)
demo.replot()
demo.resize(600, 400)
demo.show()
return demo
# make()
def main(args):
app = Qt.QApplication(args)
demo = make()
sys.exit(app.exec_())
# main()
# Admire
if __name__ == '__main__':
main(sys.argv)
# Local Variables: ***
# mode: python ***
# End: ***
|