dynamically adding/removing axes from MultiplePlotAxes

203 views
Skip to first unread message

Efrem Braun

unread,
Jan 25, 2021, 12:31:03 PM1/25/21
to pyqtgraph
Hello,

In my program, I'd like the user to be able to choose whether lines are plotted or not. I do this with a button which the user can click for each line to show or hide that line. If the user chooses to hide the line, the pen gets set to None.

I'm using multiple axes for this plot, and I'd like the axes to disappear if the user is not displaying the line shown on a particular axis. I'm using a variant of the example code shown at https://github.com/pyqtgraph/pyqtgraph/blob/master/examples/MultiplePlotAxes.py.

For the "regular" right-y-axis (p2), it's easier to hide and re-show the axis with `p1.showAxis('right', show=False)` and `p1.showAxis('right', show=True)`. However, for the addition right-y-axis (p3), I'm having trouble figuring out how to do this. In theory, I should be able to do `p1.layout.removeItem(ax3)` and then `p1.layout.addItem(ax3, 2, 3)`. However, when I "remove" the axis, it doesn't get removed, but rather gets moved over to the top-left of the plot.

Any idea what's going on? My code is below. I just took the code at https://github.com/pyqtgraph/pyqtgraph/blob/master/examples/MultiplePlotAxes.py and added the removal of the axes to make it as simple as possible to debug.

Thanks.

Efrem Braun


```

import pyqtgraph as pg

from pyqtgraph.Qt import QtCore, QtGui

import numpy as np


pg.mkQApp()


pw = pg.PlotWidget()

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.scene().addItem(p2)

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

p2.setXLink(p1)

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


## create third ViewBox. 

## this time we need to create a new axis as well.

p3 = pg.ViewBox()

ax3 = pg.AxisItem('right')

p1.layout.addItem(ax3, 2, 3)

p1.scene().addItem(p3)

ax3.linkToView(p3)

p3.setXLink(p1)

ax3.setZValue(-10000)

ax3.setLabel('axis 3', color='#ff0000')



## Handle view resizing 

def updateViews():

    ## view has resized; update auxiliary views to match

    global p1, p2, p3

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

    p3.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)

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


updateViews()

p1.vb.sigResized.connect(updateViews)



p1.plot([1,2,4,8,16,32])

p2.addItem(pg.PlotCurveItem([10,20,40,80,40,20], pen='b'))

p3.addItem(pg.PlotCurveItem([3200,1600,800,400,200,100], pen='r'))


p1.showAxis('right', show=False) # My code modification

#p1.showAxis('right', show=True) # My code modification


p1.layout.removeItem(ax3) # My code modification

#p1.layout.addItem(ax3, 2, 3) # My code modification


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

```

Efrem Braun

unread,
Jan 25, 2021, 1:44:32 PM1/25/21
to pyqtgraph
Well, it's a silly workaround, but adding:

```

ax3.setPen(None)

ax3.showLabel(False)

ax3.style['showValues'] = False

```

after removing the ax3 item does hide the axis from view. There should definitely be a more elegant solution though.

Efrem Braun
Reply all
Reply to author
Forward
0 new messages