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.