Показать строковые значения на оси x в pyqtgraph

Я хочу отобразить строковые значения для ТИКов на оси x в pyqtgraph. Прямо сейчас я не могу понять, как это сделать.

Ex:

x = ['a', 'b', 'c', 'd', 'e', 'f']
y = [1, 2, 3, 4, ,5, 6]
pg.plot(x, y) 

когда я пытаюсь передать массив строк в x переменная пытается преобразовать это в float и разбивает GUI с сообщением об ошибке.

2 ответов


обычно в pyqtgraph при работе с пользовательскими строками оси люди подкласса AxisItem и переопределить tickStrings со строками, которые они хотят отобразить.

см., например,pyqtgraph: как построить временной ряд (дата и время на оси x)?

Pyqtgraphs axisitem также имеет встроенный setTicks что позволяет указать тики, которые будут отображаться, это может быть сделано для простой проблемы, как это вместо подкласса AxisItem.


построение графика с пользовательской строкой на оси x может быть сделано следующим образом.

  • создать dict с x-значениями вместе со строками для отображения на оси.

xdict = {0:'a', 1:'b', 2:'c', 3:'d', 4:'e', 5:'f'}

и с помощью

x = ['a', 'b', 'c', 'd', 'e', 'f']
xdict = dict(enumerate(x))
  • использовать setTicks в AxisItem или Подкласс AxisItem и в tickStrings найти строку, соответствующую значение.

1. Использование стандартного Pyqtgraph AxisItem и setTicks

    from PyQt4 import QtCore
    import pyqtgraph as pg

    x = ['a', 'b', 'c', 'd', 'e', 'f']
    y = [1, 2, 3, 4, 5, 6]
    xdict = dict(enumerate(x))

    win = pg.GraphicsWindow()
    stringaxis = pg.AxisItem(orientation='bottom')
    stringaxis.setTicks([xdict.items()])
    plot = win.addPlot(axisItems={'bottom': stringaxis})
    curve = plot.plot(list(xdict.keys()),y)

    if __name__ == '__main__':
        import sys
        if sys.flags.interactive != 1 or not hasattr(QtCore, 'PYQT_VERSION'):
            pg.QtGui.QApplication.exec_()

2. Реализация путем подкласса AxisItem

это более общий метод, который можно легко изменить на все виды забавных вещей, например, преобразование метки времени unix в дату.

    from PyQt4 import QtCore
    import pyqtgraph as pg
    import numpy as np

    class MyStringAxis(pg.AxisItem):
        def __init__(self, xdict, *args, **kwargs):
            pg.AxisItem.__init__(self, *args, **kwargs)
            self.x_values = np.asarray(xdict.keys())
            self.x_strings = xdict.values()

        def tickStrings(self, values, scale, spacing):
            strings = []
            for v in values:
                # vs is the original tick value
                vs = v * scale
                # if we have vs in our values, show the string
                # otherwise show nothing
                if vs in self.x_values:
                    # Find the string with x_values closest to vs
                    vstr = self.x_strings[np.abs(self.x_values-vs).argmin()]
                else:
                    vstr = ""
                strings.append(vstr)
            return strings

    x = ['a', 'b', 'c', 'd', 'e', 'f']
    y = [1, 2, 3, 4, 5, 6]
    xdict = dict(enumerate(x))

    win = pg.GraphicsWindow()
    stringaxis = MyStringAxis(xdict, orientation='bottom')
    plot = win.addPlot(axisItems={'bottom': stringaxis})
    curve = plot.plot(list(xdict.keys()),y)

    if __name__ == '__main__':
        import sys
        if sys.flags.interactive != 1 or not hasattr(QtCore, 'PYQT_VERSION'):
            pg.QtGui.QApplication.exec_()

скриншот с примером: Screenshot from example


мне проще всего подготовить список индексов и список ваших строк, а затем zip их вместе:

ticks = [list(zip(range(5), ('a', 'b', 'c', 'd', 'e')))]

вы можете получить существующую AxisItem PlotWidget следующим образом:

pw = pg.PlotWidget()
xax = pw.getAxis('bottom')

и, наконец, установите тики оси так:

xax.setTicks(ticks)

насколько я могу судить, PlotWidgets автоматически включает "нижние" и "левые" Аксиситемы, но вы можете создавать и добавлять другие, если хотите.