Я пытаюсь создать графики параллельных координат с помощью PyQtGraph. У меня есть два возможных подхода: либо несколько элементов PlotItem рядом, либо несколько ViewBox (например, MultiplePlotAxes.py, пример ). В любом случае точки должны быть нарисованы на AxisItems, а не рядом (затем вручную нарисованы линии для соединения точек).
Я собрал (очень грубый) пример того, что я зашло так далеко. Для каждой оси точки нанесены при x = 0. Они нарисованы рядом с осью y. Вы можете щелкнуть и перетащить точки ближе к оси, но они начинают исчезать при перетаскивании на нее.
from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph import PlotWidget, PlotItem, PlotDataItem, AxisItem
import numpy as np
import pandas as pd
class ParallelCoordinatePlotObject(QtGui.QWidget):
def __init__(self, df, style, key):
super().__init__()
self.layout = QtGui.QHBoxLayout()
self.setLayout(self.layout)
self.layout.setContentsMargins(1,1,1,1)
self.layout.setSpacing(0)
self.setContentsMargins(1,1,1,1)
# list of axis names
cols = list(df.columns)
cols.remove(key)
# data series names
self.names = list(style.keys())
self.makeAxes(cols)
self.plotData(style)
def makeAxes(self, cols):
self.plotItems = {}
for column in cols:
pw = PlotWidget(background='#ffffff')
item = pw.getPlotItem()
item.setLabel('left', column)
self.plotItems[column] = item
item.hideAxis('bottom')
self.layout.addWidget(pw)
def plotData(self, style):
for column, item in self.plotItems.items(): # for each axis
for name in self.names: # for each data series
points = np.array(df.query(f'Name=="{name}"')[column])
x = np.zeros(len(points))
data = np.stack([x, points], axis=-1)
colour = style[name]['colour']
symbol = style[name]['symbol']
item.plot(data, pen=None, symbol=symbol, symbolPen=colour,
symbolBrush=None)
df = pd.read_csv('https://raw.githubusercontent.com/pandas-dev/pandas/master/pandas/tests/io/data/csv/iris.csv')
c = iter(['r', 'g', 'b'])
s = iter(['x', 'o', '+'])
style = {name:{'colour':next(c), 'symbol':next(s)} for name in set(df['Name'])}
app = QtGui.QApplication([])
mw = QtGui.QMainWindow()
mw.setWindowTitle('Parallel Coordinate Plot')
mw.resize(800,800)
mw.show()
cw = ParallelCoordinatePlotObject(df, style, key='Name')
mw.setCentralWidget(cw)
## 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_()
Я думаю, проблема может заключаться в том, что PlotItem добавляет оси и поле просмотра в QGraphicsGridLayout , поэтому элементы в окне просмотра не смогут перекрывать ось, поскольку они находятся в отдельных столбцах. Я попытался создать отдельные элементы AxisItems в makeAxes
и добавить их с помощью PlotItem.addItem
(это также потребовало переопределения AxisItem.setLogMode
, поскольку PlotItem.addItem
вызывает setLogMode
данного элемента с двумя аргументы). Однако нарисованный AxisItem был огромным, серым, перевернутым и перевернутым.
Я использую PyQtGraph 0.11.0 и Python 3.6.2.
Любая помощь с был бы очень признателен :)
Потенциально полезная ссылка: лучшая Python реализация параллельных координатных графиков, которую я смог найти, была этот ответ , который использует twinx
* 1027 matplotlib * метод создания осей, затем spine.set_position
для их размещения, но я бы хотел иметь возможность использовать PyQtGraph, поскольку интерактивные возможности действительно полезны (а графики встраиваются в приложение PySide2) .