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()

[image: Screenshot from 2020-11-16 16-15-35.png]

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 
> <+358%2050%2046728972>, 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 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/317cbddd-ce69-42aa-83fc-6bb91949ae69n%40googlegroups.com.

Reply via email to