Why pyqtgraph legend text cannot contain special characters like: '>', '<'
Question:
I am plotting data with pyqtgraph inside a PySide6 Application.
Anyways, the problem is that the text gets cut off if a name contains a special character like ‘<‘ or ‘>’.
Here is a minimal example:
from PySide6 import QtCore, QtWidgets
import pyqtgraph as pg
plt = pg.plot()
plt.addLegend()
c1 = plt.plot([1,2,3], pen='r', name="TEST_O<C_C*0.99>=H")
c2 = plt.plot([3,2,1], pen='g', name='green plot test blabla')
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtWidgets.QApplication.instance().exec()
Which outputs:
Why does this happen?
Is there a work-around without replacing the characters?
Answers:
I’d wager it’s being interpreted as an HTML tag.
Try "TEST_O<C_C*0.99>=H"
, or, programmatically,
import html
# ...
c1 = plt.plot([1,2,3], pen='r', name=html.escape("TEST_O<C_C*0.99>=H"))
The issue you are experiencing is due to the fact that ‘<‘ and ‘>’ are used as escape characters for HTML-like tags in PyQtGraph text items, including labels in the legend. When you use these characters in your name, PyQtGraph attempts to parse them as tags, which can lead to unexpected results.
To work around this issue without replacing the characters, you can subclass pg.LegendItem and override the _addItemToLayout method to set the text of the labels as plain text instead of rich text (HTML). Here’s a modified version of your example that demonstrates how to do this:
from PySide6 import QtCore, QtWidgets
import pyqtgraph as pg
class CustomLegendItem(pg.LegendItem):
def _addItemToLayout(self, item):
label = item[1]
row = self.layout.rowCount()
self.layout.addItem(item[0], row, 0)
self.layout.addItem(label, row, 1)
label.setText(label.text(), mode='text') # Set the text as plain text
def main():
app = QtWidgets.QApplication([])
win = QtWidgets.QMainWindow()
plt = pg.PlotWidget()
win.setCentralWidget(plt)
win.show()
custom_legend = CustomLegendItem()
plt.addItem(custom_legend)
custom_legend.setParentItem(plt.getPlotItem())
c1 = plt.plot([1, 2, 3], pen='r', name="TEST_O<C_C*0.99>=H")
c2 = plt.plot([3, 2, 1], pen='g', name='green plot test blabla')
custom_legend.addItem(c1, "TEST_O<C_C*0.99>=H")
custom_legend.addItem(c2, "green plot test blabla")
sys.exit(app.exec())
if __name__ == '__main__':
import sys
main()
I am plotting data with pyqtgraph inside a PySide6 Application.
Anyways, the problem is that the text gets cut off if a name contains a special character like ‘<‘ or ‘>’.
Here is a minimal example:
from PySide6 import QtCore, QtWidgets
import pyqtgraph as pg
plt = pg.plot()
plt.addLegend()
c1 = plt.plot([1,2,3], pen='r', name="TEST_O<C_C*0.99>=H")
c2 = plt.plot([3,2,1], pen='g', name='green plot test blabla')
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtWidgets.QApplication.instance().exec()
Which outputs:
Why does this happen?
Is there a work-around without replacing the characters?
I’d wager it’s being interpreted as an HTML tag.
Try "TEST_O<C_C*0.99>=H"
, or, programmatically,
import html
# ...
c1 = plt.plot([1,2,3], pen='r', name=html.escape("TEST_O<C_C*0.99>=H"))
The issue you are experiencing is due to the fact that ‘<‘ and ‘>’ are used as escape characters for HTML-like tags in PyQtGraph text items, including labels in the legend. When you use these characters in your name, PyQtGraph attempts to parse them as tags, which can lead to unexpected results.
To work around this issue without replacing the characters, you can subclass pg.LegendItem and override the _addItemToLayout method to set the text of the labels as plain text instead of rich text (HTML). Here’s a modified version of your example that demonstrates how to do this:
from PySide6 import QtCore, QtWidgets
import pyqtgraph as pg
class CustomLegendItem(pg.LegendItem):
def _addItemToLayout(self, item):
label = item[1]
row = self.layout.rowCount()
self.layout.addItem(item[0], row, 0)
self.layout.addItem(label, row, 1)
label.setText(label.text(), mode='text') # Set the text as plain text
def main():
app = QtWidgets.QApplication([])
win = QtWidgets.QMainWindow()
plt = pg.PlotWidget()
win.setCentralWidget(plt)
win.show()
custom_legend = CustomLegendItem()
plt.addItem(custom_legend)
custom_legend.setParentItem(plt.getPlotItem())
c1 = plt.plot([1, 2, 3], pen='r', name="TEST_O<C_C*0.99>=H")
c2 = plt.plot([3, 2, 1], pen='g', name='green plot test blabla')
custom_legend.addItem(c1, "TEST_O<C_C*0.99>=H")
custom_legend.addItem(c2, "green plot test blabla")
sys.exit(app.exec())
if __name__ == '__main__':
import sys
main()