Показать строковые значения на оси 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_()
мне проще всего подготовить список индексов и список ваших строк, а затем zip
их вместе:
ticks = [list(zip(range(5), ('a', 'b', 'c', 'd', 'e')))]
вы можете получить существующую AxisItem PlotWidget следующим образом:
pw = pg.PlotWidget()
xax = pw.getAxis('bottom')
и, наконец, установите тики оси так:
xax.setTicks(ticks)
насколько я могу судить, PlotWidgets автоматически включает "нижние" и "левые" Аксиситемы, но вы можете создавать и добавлять другие, если хотите.