Dear Patrik,

Thanks for your input, half of my problem (dual Y axis) is solved with your provided example. Other thing that I need to fix my graph is; I would like one of the plot (lets say the yellow one in your example) is to be kept fixed (non-moveable) while the plot (red) is flexible (moveable) on both axis. The objective is to match the performance of two plots by means of over lapping each other. I tried through GraphicsView and ViewBox and its working there but I’m unable to introduce Log scale in the Y axis liked to the View/Graphics View.

 

What I want to see in brief:

A single graph window with multiple axis (all in Log scale), where one plot remain fixed while the other plot remain flexible for overlapping/ tracing the two plots performance.

 

I’ll be glad if I can have some solution accordingly.

Regards,

Fahad.

 

Sent from Mail for Windows 10

 

From: Patrick
Sent: Sunday, November 15, 2020 11:47 PM
To: pyqtgraph
Subject: [pyqtgraph] Re: Log Scale with Multiple Plots/ Multiple Axis

 

Hi,

 

I don't exactly understand what you're trying to do, but I implemented dual-scale axes using a custom AxisItem class which applies a conversion function to produce the labels for the second axis. It works something like this:

 

from PyQt5 import QtCore, QtWidgets
import pyqtgraph as pg
import numpy as np
import warnings


class AxisItemScaleFunction(pg.AxisItem):
    """Extension of pyqtgraph AxisItem which allows the axis tick labels to be
    transformed using a user-specified function.

    Typical use would be to display the same axis data in two different unit
    systems. For example, temperature in C and F, or light wavelength as well as
    photon energy.

    Note that the axis range and scale is not changed, only the calculation of
    the axis tick labels."""

    def __init__(self, orientation, pen=None, linkView=None, parent=None, maxTickLength=-5, showValues=True, scalefunc=lambda x: x):
        self.scalefunc = scalefunc
        pg.AxisItem.__init__(self, orientation, pen=pen, linkView=linkView, parent=parent, maxTickLength=maxTickLength, showValues=showValues)

    def tickStrings(self, values, scale, spacing):
        """Generates the strings to use for tick labels."""
        if self.logMode:
            return self.logTickStrings(values, scale, spacing)

        warnings.simplefilter("ignore")
        try:
            places = np.nanmax([0,
                np.ceil(-np.log10((np.abs(self.scalefunc(values[0] + spacing) - self.scalefunc(values[0])))*scale)),
                np.ceil(-np.log10((np.abs(self.scalefunc(values[-1]) - self.scalefunc(values[-1] - spacing)))*scale))])
        except IndexError:
            places = 0
        warnings.simplefilter("default")
        strings = []
        for v in values:
            vs = self.scalefunc(v) * scale
            if abs(vs) < .001 or abs(vs) >= 10000:
                vstr = "%g" % vs
            else:
                vstr = ("%%0.%df" % places) % vs
            strings.append(vstr)
        return strings

    def updateAutoSIPrefix(self):
        """Update the SI prefix for units, if displayed."""
        if self.label.isVisible():
            (scale, prefix) = pg.siScale(max(abs(self.scalefunc(self.range[0])), abs(self.scalefunc(self.range[1]))))
            if self.labelUnits == '' and prefix in ['k', 'm']:  ## If we are not showing units, wait until 1e6 before scaling.
                scale = 1.0
                prefix = ''
            self.setLabel(unitPrefix=prefix)
        else:
            scale = 1.0

        self.autoSIPrefixScale = scale
        self.picture = None
        self.update()

    def logTickStrings(self, values, scale, spacing):
        """Return tick strings for a logarithmic axis."""
        # This one-line abomination isn't tested very extensively but seems to work...
        return ["%0.1g"%x for x in np.array([self.scalefunc(v) for v in 10 ** np.array(values).astype(float)])]


class TwinScales(pg.GraphicsLayoutWidget):

    def __init__(self):
        super().__init__()
        rax = AxisItemScaleFunction(orientation='right', scalefunc=lambda x: 2.998e5/x if not x == 0 else np.inf)
        self.spectrum = self.addPlot(row=0, col=0, axisItems={'right': rax}, enableMenu=False)
        self.spectrum.showGrid(x=True, y=True)
        self.spectrum.addLegend(offset=(-10, 5))
        self.spectrum.setLabels(left="Frequency (THz)", bottom="Intensity (a.u.)", right="Wavelength (nm)")

        y = np.linspace(400, 800, num=200)
        self.p1 = self.spectrum.plot(56.7*np.sin(y/20), y, pen=(255, 255, 0), name="Spectral slice t = 123.4 fs")
        self.p2 = self.spectrum.plot(45.6*np.cos(y/30), y, pen=(255, 0, 0), name="Other slice t = 567.8 fs")

        self.spectrum.setLogMode(x=False, y=True)


def main():
    import sys
    app = QtWidgets.QApplication(sys.argv)
    mainwindow = TwinScales()
    mainwindow.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

 

 

Hopefully that might help you.

 

Patrick

 

 

On Saturday, 14 November 2020 at 9:29:50 pm UTC+10:30 [email protected] wrote:

I'm trying to plot 2 different plots in a single graph window (Sample Code given below). I'm using ViewBox to bring an independent 2nd y axis but I'm unable to apply log scale on both x and the y axis for the 2nd plot being plotted through View Box. Also please let me know if I can add a legend for the 2ns plot in vb as well !!! Can I have any solution please ?  

import pyqtgraph as pg

from pyqtgraph.Qt import QtCore, QtGui

import numpy as np

import pandas as pd

 

pg.mkQApp()

 

pw = pg.PlotWidget()

legend = pw.plotItem.legend

pw.plotItem.addLegend(offset=(50, 10))

pw.plotItem.addLegend()

pw.setLogMode(x=True, y=True)

 

 

pw.show()

pw.setWindowTitle('pyqtgraph example: MultiplePlotAxes')

p1 = pw.plotItem

p1.setLabels(left='axis 1')

 

## create a new ViewBox, link the right axis to its coordinate system

p2 = pg.ViewBox()

 

p1.showAxis('right')

p1.setLogMode(x=True, y=True)

p1.scene().addItem(p2)

 

p1.getAxis('right').linkToView(p2)

 

p1.getAxis('right').setLogMode(True)

p1.getAxis('left').setLogMode(False)

p1.getAxis('bottom').setLogMode(True)

#p1.getAxis('bottom').linkToView(p2)

#p2.setXLink(p1)

p1.getAxis('right').setTicks(False)  #.setLabel('axis2', color='#0000ff')

 

 

## Handle view resizing

def updateViews():

    ## view has resized; update auxiliary views to match

    global p1, p2

    p2.setGeometry(p1.vb.sceneBoundingRect())

 

 

    ## need to re-update linked axes since this was called

    ## incorrectly while views had different shapes.

    ## (probably this should be handled in ViewBox.resizeEvent)

    p2.linkedViewChanged(p1.vb, p2.XAxis)

 

 

 

updateViews()

p1.vb.sigResized.connect(updateViews)

 

x = [0.00189308411214953,        0.0586856074766355,     0.113585046728972,       0.172270654205607,              0.229063177570093,       0.751554392523364,       0.804560747663551,       0.863246355140187]

 

y1 = [20.4519856776661,             2.36731824818362,          1.37059599828579,          0.893434884015263,              0.654398170298103,       0.16233537659946,          0.136188319914979,       0.12445839587513]

 

y2 = [100.206092906091,             10.7767052017243,          6.7863521253753,            5.06574658107859,              4.13195800053371,          3.54173495603609,          3.12977548096585,          0.109898121408567]

 

 

p1.plot(x,y1, name = 'First Curve')

 

 

p2.addItem(pg.PlotCurveItem(x,y2, name = 'SecondCurve', pen='b'))

 

 

## Start Qt event loop unless running in interactive mode or using pyside.

if __name__ == '__main__':

    import sys

 

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):

        QtGui.QApplication.instance().exec_()

--
You received this message because you are subscribed to a topic in the Google Groups "pyqtgraph" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pyqtgraph/pjogNHybJAE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to [email protected].
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/317cbddd-ce69-42aa-83fc-6bb91949ae69n%40googlegroups.com.

 

--
You received this message because you are subscribed to the Google Groups "pyqtgraph" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion on the web visit https://groups.google.com/d/msgid/pyqtgraph/A3A8E777-9C22-448F-B2E1-246AA689F7EC%40hxcore.ol.

Reply via email to