Exemple #1
0
    def drawValues(self, qp: QtGui.QPainter):
        if len(self.data) == 0 and len(self.reference) == 0:
            return
        pen = QtGui.QPen(Chart.color.sweep)
        pen.setWidth(self.dim.point)
        line_pen = QtGui.QPen(Chart.color.sweep)
        line_pen.setWidth(self.dim.line)
        highlighter = QtGui.QPen(QtGui.QColor(20, 0, 255))
        highlighter.setWidth(1)

        self._set_start_stop()

        # Draw bands if required
        if self.bands.enabled:
            self.drawBands(qp, self.fstart, self.fstop)

        min_value, max_value = self._find_scaling()
        self.maxValue = max_value
        self.minValue = min_value
        span = max_value - min_value
        if span == 0:
            logger.info("Span is zero for %s-Chart, setting to a small value.",
                        self.name)
            span = 1e-15
        self.span = span

        target_ticks = math.floor(self.dim.height / 60)
        fmt = Format(max_nr_digits=1)
        for i in range(target_ticks):
            val = min_value + (i / target_ticks) * span
            y = self.topMargin + round(
                (self.maxValue - val) / self.span * self.dim.height)
            qp.setPen(Chart.color.text)
            if val != min_value:
                valstr = str(Value(val, fmt=fmt))
                qp.drawText(3, y + 3, valstr)
            qp.setPen(QtGui.QPen(Chart.color.foreground))
            qp.drawLine(self.leftMargin - 5, y,
                        self.leftMargin + self.dim.width, y)

        qp.setPen(QtGui.QPen(Chart.color.foreground))
        qp.drawLine(self.leftMargin - 5, self.topMargin,
                    self.leftMargin + self.dim.width, self.topMargin)
        qp.setPen(Chart.color.text)
        qp.drawText(3, self.topMargin + 4, str(Value(max_value, fmt=fmt)))
        qp.drawText(3, self.dim.height + self.topMargin,
                    str(Value(min_value, fmt=fmt)))
        self.drawFrequencyTicks(qp)

        self.drawData(qp, self.data, Chart.color.sweep)
        self.drawData(qp, self.reference, Chart.color.reference)
        self.drawMarkers(qp)
 def test_format_digits_4(self):
     v = Value(fmt=F_DIGITS_4)
     self.assertEqual(str(v.parse("1")), "1.000")
     self.assertEqual(str(v.parse("10")), "10.00")
     self.assertEqual(str(v.parse("100")), "100.0")
     self.assertEqual(str(v.parse("1e3")), "1.000k")
     self.assertEqual(str(v.parse("1e4")), "10.00k")
     self.assertEqual(str(v.parse("1e5")), "100.0k")
     self.assertEqual(str(v.parse("1e-1")), "100.0m")
     self.assertEqual(str(v.parse("1e-2")), "10.00m")
     self.assertEqual(str(v.parse("1e-3")), "1.000m")
     self.assertEqual(v.parse("\N{INFINITY}").value, inf)
     self.assertEqual(v.parse("-\N{INFINITY}").value, -inf)
 def test_format_digits_3(self):
     v = Value(fmt=F_DIGITS_3)
     self.assertEqual(str(v.parse("1")), "1")
     self.assertEqual(str(v.parse("10")), "10")
     self.assertEqual(str(v.parse("100")), "100")
     self.assertEqual(str(v.parse("1e3")), "1k")
     self.assertEqual(str(v.parse("1e4")), "10k")
     self.assertEqual(str(v.parse("1e5")), "100k")
     self.assertEqual(str(v.parse("1e9")), "1000M")
     self.assertEqual(str(v.parse("1e-1")), "100m")
     self.assertEqual(str(v.parse("1e-2")), "10m")
     self.assertEqual(str(v.parse("1e-3")), "1m")
     self.assertEqual(str(v.parse("1e-9")), "0")
 def test_format_attributes(self):
     v = Value("10.0", "Hz", fmt=F_DIGITS_4)
     self.assertEqual(v.value, 10.0)
     v.value = 11
     self.assertEqual(v.value, 11)
     v.parse(12)
     self.assertEqual(v.value, 12)
     v.parse("12 GHz")
     self.assertEqual(v.unit, "Hz")
Exemple #5
0
 def inductanceEquivalent(im50, freq) -> str:
     if freq == 0:
         return "- nH"
     inductance = im50 * 1 / (freq * 2 * math.pi)
     return str(Value(inductance, "H", Format(max_nr_digits=5, space_str=" ")))
Exemple #6
0
 def parseFrequency(freq: str) -> int:
     parser = Value(0, "Hz")
     try:
         return round(parser.parse(freq))
     except (ValueError, IndexError):
         return -1
Exemple #7
0
 def capacitanceEquivalent(im50, freq) -> str:
     if im50 == 0 or freq == 0:
         return "- pF"
     capacitance = 1 / (freq * 2 * math.pi * im50)
     return str(Value(-capacitance, "F", Format(max_nr_digits=5, space_str=" ")))
    def test_default_format(self):
        self.assertEqual(str(Value(0)), "0.00000")
        self.assertEqual(str(Value(1)), "1.00000")
        self.assertEqual(str(Value(10)), "10.0000")
        self.assertEqual(str(Value(100)), "100.000")
        self.assertEqual(str(Value(-1)), "-1.00000")
        self.assertEqual(str(Value(-10)), "-10.0000")
        self.assertEqual(str(Value(-100)), "-100.000")

        self.assertEqual(str(Value(1e3)), "1.00000k")
        self.assertEqual(str(Value(1e4)), "10.0000k")
        self.assertEqual(str(Value(1e5)), "100.000k")
        self.assertEqual(str(Value(1e6)), "1.00000M")
        self.assertEqual(str(Value(1e7)), "10.0000M")
        self.assertEqual(str(Value(1e8)), "100.000M")
        self.assertEqual(str(Value(1e9)), "1.00000G")
        self.assertEqual(str(Value(1e12)), "1.00000T")
        self.assertEqual(str(Value(1e15)), "1.00000P")
        self.assertEqual(str(Value(1e18)), "1.00000E")
        self.assertEqual(str(Value(1e21)), "1.00000Z")
        self.assertEqual(str(Value(1e24)), "1.00000Y")
        self.assertEqual(str(Value(1e27)), "\N{INFINITY}")
        self.assertEqual(str(Value(-1e27)), "-\N{INFINITY}")
        self.assertEqual(float(Value(1e27)), 1e27)

        self.assertEqual(str(Value(.1)), "100.000m")
        self.assertEqual(str(Value(.01)), "10.0000m")
        self.assertEqual(str(Value(.001)), "1.00000m")
        self.assertEqual(str(Value(1e-6)), "1.00000µ")
        self.assertEqual(str(Value(1e-9)), "1.00000n")
        self.assertEqual(str(Value(1e-12)), "1.00000p")
        self.assertEqual(str(Value(1e-15)), "1.00000f")
        self.assertEqual(str(Value(1e-18)), "1.00000a")
        self.assertEqual(str(Value(1e-21)), "1.00000z")
        self.assertEqual(str(Value(1e-24)), "1.00000y")
        self.assertEqual(str(Value(1e-27)), "0.00100y")
        self.assertEqual(str(Value(1e-29)), "0.00001y")
        self.assertEqual(str(Value(-1e-29)), "-0.00001y")
        self.assertEqual(str(Value(1e-30)), "0.00000")
        self.assertEqual(float(Value(1e-30)), 1e-30)
Exemple #9
0
 def parseFrequency(freq: str) -> int:
     parser = Value(0, "Hz", Format(parse_sloppy_unit=True, parse_sloppy_kilo=True))
     try:
         return round(parser.parse(freq).value)
     except (ValueError, IndexError):
         return -1
    def test_default_format(self):
        self.assertEqual(str(Value(0)), "0.00000")
        self.assertEqual(str(Value(1)), "1.00000")
        self.assertEqual(str(Value(10)), "10.0000")
        self.assertEqual(str(Value(100)), "100.000")
        self.assertEqual(str(Value(-1)), "-1.00000")
        self.assertEqual(str(Value(-10)), "-10.0000")
        self.assertEqual(str(Value(-100)), "-100.000")

        self.assertEqual(str(Value(1e3)), "1.00000k")
        self.assertEqual(str(Value(1e4)), "10.0000k")
        self.assertEqual(str(Value(1e5)), "100.000k")
        self.assertEqual(str(Value(1e6)), "1.00000M")
        self.assertEqual(str(Value(1e7)), "10.0000M")
        self.assertEqual(str(Value(1e8)), "100.000M")
        self.assertEqual(str(Value(1e9)), "1.00000G")
        self.assertEqual(str(Value(1e12)), "1.00000T")
        self.assertEqual(str(Value(1e15)), "1.00000P")
        self.assertEqual(str(Value(1e18)), "1.00000E")
        self.assertEqual(str(Value(1e21)), "1.00000Z")
        self.assertEqual(str(Value(1e24)), "1.00000Y")
        self.assertEqual(str(Value(1e27)), "\N{INFINITY}")
        self.assertEqual(str(Value(-1e27)), "-\N{INFINITY}")
        self.assertEqual(float(Value(1e27)), 1e27)
        self.assertEqual(str(Value(11, fmt=Format(printable_max=10))), '')
        self.assertEqual(str(Value(11, fmt=Format(allways_signed=True))),
                         '+11.0000')

        self.assertEqual(str(Value(.1)), "100.000m")
        self.assertEqual(str(Value(.01)), "10.0000m")
        self.assertEqual(str(Value(.001)), "1.00000m")
        self.assertEqual(str(Value(1e-6)), "1.00000µ")
        self.assertEqual(str(Value(1e-9)), "1.00000n")
        self.assertEqual(str(Value(1e-12)), "1.00000p")
        self.assertEqual(str(Value(1e-15)), "1.00000f")
        self.assertEqual(str(Value(1e-18)), "1.00000a")
        self.assertEqual(str(Value(1e-21)), "1.00000z")
        self.assertEqual(str(Value(1e-24)), "1.00000y")
        self.assertEqual(str(Value(1e-27)), "0.00100y")
        self.assertEqual(str(Value(1e-29)), "0.00001y")
        self.assertEqual(str(Value(-1e-29)), "-0.00001y")
        self.assertEqual(str(Value(1e-30)), "0.00000")
        self.assertEqual(float(Value(1e-30)), 1e-30)
 def test_representation(self):
     a = Value(1)
     b = eval(repr(a))
     self.assertEqual(repr(a), repr(b))
Exemple #12
0
 def formatShortFrequency(freq):
     return str(Value(freq, "Hz", Format(max_nr_digits=4)))
Exemple #13
0
 def formatSweepFrequency(freq: Number) -> str:
     return str(Value(freq, "Hz", Format(max_nr_digits=9, allow_strip=True)))
Exemple #14
0
    def drawValues(self, qp: QtGui.QPainter):
        if len(self.data) == 0 and len(self.reference) == 0:
            return
        pen = QtGui.QPen(self.sweepColor)
        pen.setWidth(self.pointSize)
        line_pen = QtGui.QPen(self.sweepColor)
        line_pen.setWidth(self.lineThickness)
        highlighter = QtGui.QPen(QtGui.QColor(20, 0, 255))
        highlighter.setWidth(1)
        if self.fixedSpan:
            fstart = self.minFrequency
            fstop = self.maxFrequency
        else:
            if len(self.data) > 0:
                fstart = self.data[0].freq
                fstop = self.data[len(self.data) - 1].freq
            else:
                fstart = self.reference[0].freq
                fstop = self.reference[len(self.reference) - 1].freq
        self.fstart = fstart
        self.fstop = fstop

        # Draw bands if required
        if self.bands.enabled:
            self.drawBands(qp, fstart, fstop)

        # Find scaling
        if self.fixedValues:
            min_val = self.minDisplayValue
            max_val = self.maxDisplayValue
        else:
            min_val = 1000
            max_val = -1000
            for d in self.data:
                imp = d.impedance()
                re, im = imp.real, imp.imag
                re = re * 10e6 / d.freq
                im = im * 10e6 / d.freq
                if re > max_val:
                    max_val = re
                if re < min_val:
                    min_val = re
                if im > max_val:
                    max_val = im
                if im < min_val:
                    min_val = im
            for d in self.reference:  # Also check min/max for the reference sweep
                if d.freq < fstart or d.freq > fstop:
                    continue
                imp = d.impedance()
                re, im = imp.real, imp.imag
                re = re * 10e6 / d.freq
                im = im * 10e6 / d.freq
                if re > max_val:
                    max_val = re
                if re < min_val:
                    min_val = re
                if im > max_val:
                    max_val = im
                if im < min_val:
                    min_val = im

        if self.logarithmicY:
            min_val = max(0.01, min_val)

        self.max = max_val

        span = max_val - min_val
        if span == 0:
            span = 0.01
        self.span = span

        # We want one horizontal tick per 50 pixels, at most
        horizontal_ticks = math.floor(self.chartHeight / 50)
        fmt = Format(max_nr_digits=4)
        for i in range(horizontal_ticks):
            y = self.topMargin + round(i * self.chartHeight / horizontal_ticks)
            qp.setPen(QtGui.QPen(self.foregroundColor))
            qp.drawLine(self.leftMargin - 5, y,
                        self.leftMargin + self.chartWidth + 5, y)
            qp.setPen(QtGui.QPen(self.textColor))
            val = Value(self.valueAtPosition(y)[0], fmt=fmt)
            qp.drawText(3, y + 4, str(val))

        qp.drawText(3, self.chartHeight + self.topMargin,
                    str(Value(min_val, fmt=fmt)))

        self.drawFrequencyTicks(qp)

        primary_pen = pen
        secondary_pen = QtGui.QPen(self.secondarySweepColor)
        if len(self.data) > 0:
            c = QtGui.QColor(self.sweepColor)
            c.setAlpha(255)
            pen = QtGui.QPen(c)
            pen.setWidth(2)
            qp.setPen(pen)
            qp.drawLine(20, 9, 25, 9)
            c = QtGui.QColor(self.secondarySweepColor)
            c.setAlpha(255)
            pen.setColor(c)
            qp.setPen(pen)
            qp.drawLine(self.leftMargin + self.chartWidth, 9,
                        self.leftMargin + self.chartWidth + 5, 9)

        primary_pen.setWidth(self.pointSize)
        secondary_pen.setWidth(self.pointSize)
        line_pen.setWidth(self.lineThickness)

        for i in range(len(self.data)):
            x = self.getXPosition(self.data[i])
            y_re = self.getReYPosition(self.data[i])
            y_im = self.getImYPosition(self.data[i])
            qp.setPen(primary_pen)
            if self.isPlotable(x, y_re):
                qp.drawPoint(x, y_re)
            qp.setPen(secondary_pen)
            if self.isPlotable(x, y_im):
                qp.drawPoint(x, y_im)
            if self.drawLines and i > 0:
                prev_x = self.getXPosition(self.data[i - 1])
                prev_y_re = self.getReYPosition(self.data[i - 1])
                prev_y_im = self.getImYPosition(self.data[i - 1])

                # Real part first
                line_pen.setColor(self.sweepColor)
                qp.setPen(line_pen)
                if self.isPlotable(x, y_re) and self.isPlotable(
                        prev_x, prev_y_re):
                    qp.drawLine(x, y_re, prev_x, prev_y_re)
                elif self.isPlotable(
                        x, y_re) and not self.isPlotable(prev_x, prev_y_re):
                    new_x, new_y = self.getPlotable(x, y_re, prev_x, prev_y_re)
                    qp.drawLine(x, y_re, new_x, new_y)
                elif not self.isPlotable(x, y_re) and self.isPlotable(
                        prev_x, prev_y_re):
                    new_x, new_y = self.getPlotable(prev_x, prev_y_re, x, y_re)
                    qp.drawLine(prev_x, prev_y_re, new_x, new_y)

                # Imag part second
                line_pen.setColor(self.secondarySweepColor)
                qp.setPen(line_pen)
                if self.isPlotable(x, y_im) and self.isPlotable(
                        prev_x, prev_y_im):
                    qp.drawLine(x, y_im, prev_x, prev_y_im)
                elif self.isPlotable(
                        x, y_im) and not self.isPlotable(prev_x, prev_y_im):
                    new_x, new_y = self.getPlotable(x, y_im, prev_x, prev_y_im)
                    qp.drawLine(x, y_im, new_x, new_y)
                elif not self.isPlotable(x, y_im) and self.isPlotable(
                        prev_x, prev_y_im):
                    new_x, new_y = self.getPlotable(prev_x, prev_y_im, x, y_im)
                    qp.drawLine(prev_x, prev_y_im, new_x, new_y)

        primary_pen.setColor(self.referenceColor)
        line_pen.setColor(self.referenceColor)
        secondary_pen.setColor(self.secondaryReferenceColor)
        qp.setPen(primary_pen)
        if len(self.reference) > 0:
            c = QtGui.QColor(self.referenceColor)
            c.setAlpha(255)
            pen = QtGui.QPen(c)
            pen.setWidth(2)
            qp.setPen(pen)
            qp.drawLine(20, 14, 25, 14)
            c = QtGui.QColor(self.secondaryReferenceColor)
            c.setAlpha(255)
            pen = QtGui.QPen(c)
            pen.setWidth(2)
            qp.setPen(pen)
            qp.drawLine(self.leftMargin + self.chartWidth, 14,
                        self.leftMargin + self.chartWidth + 5, 14)

        for i in range(len(self.reference)):
            if self.reference[i].freq < fstart or self.reference[
                    i].freq > fstop:
                continue
            x = self.getXPosition(self.reference[i])
            y_re = self.getReYPosition(self.reference[i])
            y_im = self.getImYPosition(self.reference[i])
            qp.setPen(primary_pen)
            if self.isPlotable(x, y_re):
                qp.drawPoint(x, y_re)
            qp.setPen(secondary_pen)
            if self.isPlotable(x, y_im):
                qp.drawPoint(x, y_im)
            if self.drawLines and i > 0:
                prev_x = self.getXPosition(self.reference[i - 1])
                prev_y_re = self.getReYPosition(self.reference[i - 1])
                prev_y_im = self.getImYPosition(self.reference[i - 1])

                line_pen.setColor(self.referenceColor)
                qp.setPen(line_pen)
                # Real part first
                if self.isPlotable(x, y_re) and self.isPlotable(
                        prev_x, prev_y_re):
                    qp.drawLine(x, y_re, prev_x, prev_y_re)
                elif self.isPlotable(
                        x, y_re) and not self.isPlotable(prev_x, prev_y_re):
                    new_x, new_y = self.getPlotable(x, y_re, prev_x, prev_y_re)
                    qp.drawLine(x, y_re, new_x, new_y)
                elif not self.isPlotable(x, y_re) and self.isPlotable(
                        prev_x, prev_y_re):
                    new_x, new_y = self.getPlotable(prev_x, prev_y_re, x, y_re)
                    qp.drawLine(prev_x, prev_y_re, new_x, new_y)

                line_pen.setColor(self.secondaryReferenceColor)
                qp.setPen(line_pen)
                # Imag part second
                if self.isPlotable(x, y_im) and self.isPlotable(
                        prev_x, prev_y_im):
                    qp.drawLine(x, y_im, prev_x, prev_y_im)
                elif self.isPlotable(
                        x, y_im) and not self.isPlotable(prev_x, prev_y_im):
                    new_x, new_y = self.getPlotable(x, y_im, prev_x, prev_y_im)
                    qp.drawLine(x, y_im, new_x, new_y)
                elif not self.isPlotable(x, y_im) and self.isPlotable(
                        prev_x, prev_y_im):
                    new_x, new_y = self.getPlotable(prev_x, prev_y_im, x, y_im)
                    qp.drawLine(prev_x, prev_y_im, new_x, new_y)

        # Now draw the markers
        for m in self.markers:
            if m.location != -1:
                x = self.getXPosition(self.data[m.location])
                y_re = self.getReYPosition(self.data[m.location])
                y_im = self.getImYPosition(self.data[m.location])

                self.drawMarker(x, y_re, qp, m.color,
                                self.markers.index(m) + 1)
                self.drawMarker(x, y_im, qp, m.color,
                                self.markers.index(m) + 1)
Exemple #15
0
def parseFrequency(freq: str) -> int:
    try:
        return int(Value(freq, "Hz", FMT_PARSE))
    except (ValueError, IndexError):
        return -1
Exemple #16
0
 def formatSweepFrequency(freq: Number) -> str:
     return str(Value(freq, "Hz", FMT_SWEEP))
Exemple #17
0
 def formatShortFrequency(freq: Number) -> str:
     return str(Value(freq, "Hz", FMT_SHORT))
Exemple #18
0
 def formatFrequency(freq: Number) -> str:
     return str(Value(freq, "Hz", FMT_FREQ))
Exemple #19
0
    def drawValues(self, qp: QtGui.QPainter):
        if len(self.data) == 0 and len(self.reference) == 0:
            return
        pen = QtGui.QPen(self.sweepColor)
        pen.setWidth(self.pointSize)
        line_pen = QtGui.QPen(self.sweepColor)
        line_pen.setWidth(self.lineThickness)
        highlighter = QtGui.QPen(QtGui.QColor(20, 0, 255))
        highlighter.setWidth(1)
        if not self.fixedSpan:
            if len(self.data) > 0:
                fstart = self.data[0].freq
                fstop = self.data[len(self.data) - 1].freq
            else:
                fstart = self.reference[0].freq
                fstop = self.reference[len(self.reference) - 1].freq
            self.fstart = fstart
            self.fstop = fstop
        else:
            fstart = self.fstart = self.minFrequency
            fstop = self.fstop = self.maxFrequency

        # Draw bands if required
        if self.bands.enabled:
            self.drawBands(qp, fstart, fstop)

        if self.fixedValues:
            maxValue = self.maxDisplayValue / 10e11
            minValue = self.minDisplayValue / 10e11
            self.maxValue = maxValue
            self.minValue = minValue
        else:
            # Find scaling
            minValue = 1
            maxValue = -1
            for d in self.data:
                val = d.capacitiveEquivalent()
                if val > maxValue:
                    maxValue = val
                if val < minValue:
                    minValue = val
            for d in self.reference:  # Also check min/max for the reference sweep
                if d.freq < self.fstart or d.freq > self.fstop:
                    continue
                val = d.capacitiveEquivalent()
                if val > maxValue:
                    maxValue = val
                if val < minValue:
                    minValue = val
            self.maxValue = maxValue
            self.minValue = minValue

        span = maxValue - minValue
        if span == 0:
            logger.info(
                "Span is zero for CapacitanceChart, setting to a small value.")
            span = 1e-15
        self.span = span

        target_ticks = math.floor(self.chartHeight / 60)
        fmt = Format(max_nr_digits=1)
        for i in range(target_ticks):
            val = minValue + (i / target_ticks) * span
            y = self.topMargin + round(
                (self.maxValue - val) / self.span * self.chartHeight)
            qp.setPen(self.textColor)
            if val != minValue:
                valstr = str(Value(val, fmt=fmt))
                qp.drawText(3, y + 3, valstr)
            qp.setPen(QtGui.QPen(self.foregroundColor))
            qp.drawLine(self.leftMargin - 5, y,
                        self.leftMargin + self.chartWidth, y)

        qp.setPen(QtGui.QPen(self.foregroundColor))
        qp.drawLine(self.leftMargin - 5, self.topMargin,
                    self.leftMargin + self.chartWidth, self.topMargin)
        qp.setPen(self.textColor)
        qp.drawText(3, self.topMargin + 4, str(Value(maxValue, fmt=fmt)))
        qp.drawText(3, self.chartHeight + self.topMargin,
                    str(Value(minValue, fmt=fmt)))
        self.drawFrequencyTicks(qp)

        self.drawData(qp, self.data, self.sweepColor)
        self.drawData(qp, self.reference, self.referenceColor)
        self.drawMarkers(qp)
Exemple #20
0
    def drawValues(self, qp: QtGui.QPainter):
        if len(self.data) == 0 and len(self.reference) == 0:
            return
        pen = QtGui.QPen(Chart.color.sweep)
        pen.setWidth(self.dim.point)
        line_pen = QtGui.QPen(Chart.color.sweep)
        line_pen.setWidth(self.dim.line)
        highlighter = QtGui.QPen(QtGui.QColor(20, 0, 255))
        highlighter.setWidth(1)

        self._set_start_stop()

        # Draw bands if required
        if self.bands.enabled:
            self.drawBands(qp, self.fstart, self.fstop)

        # Find scaling
        if self.fixedValues:
            min_real = self.minDisplayReal
            max_real = self.maxDisplayReal
            min_imag = self.minDisplayImag
            max_imag = self.maxDisplayImag
        else:
            min_real = 1000
            min_imag = 1000
            max_real = 0
            max_imag = -1000
            for d in self.data:
                imp = self.impedance(d)
                re, im = imp.real, imp.imag
                if math.isinf(re):  # Avoid infinite scales
                    continue
                if re > max_real:
                    max_real = re
                if re < min_real:
                    min_real = re
                if im > max_imag:
                    max_imag = im
                if im < min_imag:
                    min_imag = im
            for d in self.reference:  # Also check min/max for the reference sweep
                if d.freq < self.fstart or d.freq > self.fstop:
                    continue
                imp = self.impedance(d)
                re, im = imp.real, imp.imag
                if math.isinf(re):  # Avoid infinite scales
                    continue
                if re > max_real:
                    max_real = re
                if re < min_real:
                    min_real = re
                if im > max_imag:
                    max_imag = im
                if im < min_imag:
                    min_imag = im

            # Always have at least 8 numbered horizontal lines
            max_real = max(8, math.ceil(max_real))
            min_real = max(
                0, math.floor(min_real))  # Negative real resistance? No.
            max_imag = math.ceil(max_imag)
            min_imag = math.floor(min_imag)

            if max_imag - min_imag < 8:
                missing = 8 - (max_imag - min_imag)
                max_imag += math.ceil(missing / 2)
                min_imag -= math.floor(missing / 2)

            if 0 > max_imag > -2:
                max_imag = 0
            if 0 < min_imag < 2:
                min_imag = 0

            if (max_imag - min_imag) > 8 and min_imag < 0 < max_imag:
                # We should show a "0" line for the reactive part
                span = max_imag - min_imag
                step_size = span / 8
                if max_imag < step_size:
                    # The 0 line is the first step after the top. Scale accordingly.
                    max_imag = -min_imag / 7
                elif -min_imag < step_size:
                    # The 0 line is the last step before the bottom. Scale accordingly.
                    min_imag = -max_imag / 7
                else:
                    # Scale max_imag to be a whole factor of min_imag
                    num_min = math.floor(min_imag / step_size * -1)
                    num_max = 8 - num_min
                    max_imag = num_max * (min_imag / num_min) * -1

        self.max_real = max_real
        self.max_imag = max_imag

        span_real = max_real - min_real
        if span_real == 0:
            span_real = 0.01
        self.span_real = span_real

        span_imag = max_imag - min_imag
        if span_imag == 0:
            span_imag = 0.01
        self.span_imag = span_imag

        # We want one horizontal tick per 50 pixels, at most
        horizontal_ticks = math.floor(self.dim.height / 50)

        fmt = Format(max_nr_digits=3)
        for i in range(horizontal_ticks):
            y = self.topMargin + round(i * self.dim.height / horizontal_ticks)
            qp.setPen(QtGui.QPen(Chart.color.foreground))
            qp.drawLine(self.leftMargin - 5, y,
                        self.leftMargin + self.dim.width + 5, y)
            qp.setPen(QtGui.QPen(Chart.color.text))
            re = max_real - i * span_real / horizontal_ticks
            im = max_imag - i * span_imag / horizontal_ticks
            qp.drawText(3, y + 4, str(Value(re, fmt=fmt)))
            qp.drawText(self.leftMargin + self.dim.width + 8, y + 4,
                        str(Value(im, fmt=fmt)))

        qp.drawText(3, self.dim.height + self.topMargin,
                    str(Value(min_real, fmt=fmt)))
        qp.drawText(self.leftMargin + self.dim.width + 8,
                    self.dim.height + self.topMargin,
                    str(Value(min_imag, fmt=fmt)))

        self.drawFrequencyTicks(qp)

        primary_pen = pen
        secondary_pen = QtGui.QPen(Chart.color.sweep_secondary)
        if len(self.data) > 0:
            c = QtGui.QColor(Chart.color.sweep)
            c.setAlpha(255)
            pen = QtGui.QPen(c)
            pen.setWidth(2)
            qp.setPen(pen)
            qp.drawLine(20, 9, 25, 9)
            c = QtGui.QColor(Chart.color.sweep_secondary)
            c.setAlpha(255)
            pen.setColor(c)
            qp.setPen(pen)
            qp.drawLine(self.leftMargin + self.dim.width, 9,
                        self.leftMargin + self.dim.width + 5, 9)

        primary_pen.setWidth(self.dim.point)
        secondary_pen.setWidth(self.dim.point)
        line_pen.setWidth(self.dim.line)

        for i in range(len(self.data)):
            x = self.getXPosition(self.data[i])
            y_re = self.getReYPosition(self.data[i])
            y_im = self.getImYPosition(self.data[i])
            qp.setPen(primary_pen)
            if self.isPlotable(x, y_re):
                qp.drawPoint(x, y_re)
            qp.setPen(secondary_pen)
            if self.isPlotable(x, y_im):
                qp.drawPoint(x, y_im)
            if self.flag.draw_lines and i > 0:
                prev_x = self.getXPosition(self.data[i - 1])
                prev_y_re = self.getReYPosition(self.data[i - 1])
                prev_y_im = self.getImYPosition(self.data[i - 1])

                # Real part first
                line_pen.setColor(Chart.color.sweep)
                qp.setPen(line_pen)
                if self.isPlotable(x, y_re) and self.isPlotable(
                        prev_x, prev_y_re):
                    qp.drawLine(x, y_re, prev_x, prev_y_re)
                elif self.isPlotable(
                        x, y_re) and not self.isPlotable(prev_x, prev_y_re):
                    new_x, new_y = self.getPlotable(x, y_re, prev_x, prev_y_re)
                    qp.drawLine(x, y_re, new_x, new_y)
                elif not self.isPlotable(x, y_re) and self.isPlotable(
                        prev_x, prev_y_re):
                    new_x, new_y = self.getPlotable(prev_x, prev_y_re, x, y_re)
                    qp.drawLine(prev_x, prev_y_re, new_x, new_y)

                # Imag part second
                line_pen.setColor(Chart.color.sweep_secondary)
                qp.setPen(line_pen)
                if self.isPlotable(x, y_im) and self.isPlotable(
                        prev_x, prev_y_im):
                    qp.drawLine(x, y_im, prev_x, prev_y_im)
                elif self.isPlotable(
                        x, y_im) and not self.isPlotable(prev_x, prev_y_im):
                    new_x, new_y = self.getPlotable(x, y_im, prev_x, prev_y_im)
                    qp.drawLine(x, y_im, new_x, new_y)
                elif not self.isPlotable(x, y_im) and self.isPlotable(
                        prev_x, prev_y_im):
                    new_x, new_y = self.getPlotable(prev_x, prev_y_im, x, y_im)
                    qp.drawLine(prev_x, prev_y_im, new_x, new_y)

        primary_pen.setColor(Chart.color.reference)
        line_pen.setColor(Chart.color.reference)
        secondary_pen.setColor(Chart.color.reference_secondary)
        qp.setPen(primary_pen)
        if len(self.reference) > 0:
            c = QtGui.QColor(Chart.color.reference)
            c.setAlpha(255)
            pen = QtGui.QPen(c)
            pen.setWidth(2)
            qp.setPen(pen)
            qp.drawLine(20, 14, 25, 14)
            c = QtGui.QColor(Chart.color.reference_secondary)
            c.setAlpha(255)
            pen = QtGui.QPen(c)
            pen.setWidth(2)
            qp.setPen(pen)
            qp.drawLine(self.leftMargin + self.dim.width, 14,
                        self.leftMargin + self.dim.width + 5, 14)

        for i in range(len(self.reference)):
            if self.reference[i].freq < self.fstart or self.reference[
                    i].freq > self.fstop:
                continue
            x = self.getXPosition(self.reference[i])
            y_re = self.getReYPosition(self.reference[i])
            y_im = self.getImYPosition(self.reference[i])
            qp.setPen(primary_pen)
            if self.isPlotable(x, y_re):
                qp.drawPoint(x, y_re)
            qp.setPen(secondary_pen)
            if self.isPlotable(x, y_im):
                qp.drawPoint(x, y_im)
            if self.flag.draw_lines and i > 0:
                prev_x = self.getXPosition(self.reference[i - 1])
                prev_y_re = self.getReYPosition(self.reference[i - 1])
                prev_y_im = self.getImYPosition(self.reference[i - 1])

                line_pen.setColor(Chart.color.reference)
                qp.setPen(line_pen)
                # Real part first
                if self.isPlotable(x, y_re) and self.isPlotable(
                        prev_x, prev_y_re):
                    qp.drawLine(x, y_re, prev_x, prev_y_re)
                elif self.isPlotable(
                        x, y_re) and not self.isPlotable(prev_x, prev_y_re):
                    new_x, new_y = self.getPlotable(x, y_re, prev_x, prev_y_re)
                    qp.drawLine(x, y_re, new_x, new_y)
                elif not self.isPlotable(x, y_re) and self.isPlotable(
                        prev_x, prev_y_re):
                    new_x, new_y = self.getPlotable(prev_x, prev_y_re, x, y_re)
                    qp.drawLine(prev_x, prev_y_re, new_x, new_y)

                line_pen.setColor(Chart.color.reference_secondary)
                qp.setPen(line_pen)
                # Imag part second
                if self.isPlotable(x, y_im) and self.isPlotable(
                        prev_x, prev_y_im):
                    qp.drawLine(x, y_im, prev_x, prev_y_im)
                elif self.isPlotable(
                        x, y_im) and not self.isPlotable(prev_x, prev_y_im):
                    new_x, new_y = self.getPlotable(x, y_im, prev_x, prev_y_im)
                    qp.drawLine(x, y_im, new_x, new_y)
                elif not self.isPlotable(x, y_im) and self.isPlotable(
                        prev_x, prev_y_im):
                    new_x, new_y = self.getPlotable(prev_x, prev_y_im, x, y_im)
                    qp.drawLine(prev_x, prev_y_im, new_x, new_y)

        # Now draw the markers
        for m in self.markers:
            if m.location != -1:
                x = self.getXPosition(self.data[m.location])
                y_re = self.getReYPosition(self.data[m.location])
                y_im = self.getImYPosition(self.data[m.location])

                self.drawMarker(x, y_re, qp, m.color,
                                self.markers.index(m) + 1)
                self.drawMarker(x, y_im, qp, m.color,
                                self.markers.index(m) + 1)