我正在使用 pyqtgraph 绘制带有一些子图和共享 X 轴的图。但是,当刻度标签具有不同长度时,Y 轴不会彼此对齐。尽管刻度标签或轴标签的大小存在差异,如何使绘图正确排列?
from pyqtgraph import QtGui, QtCore
import pyqtgraph as pg
import numpy as np
# Make up some data ----------
x = np.linspace(0, 80, 81)
y1 = np.sqrt(x)
y2 = 10*x**2
# Set up the plot ----------
# Switch to using white background and black foreground
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
app = QtGui.QApplication([])
pw = pg.GraphicsWindow(title="plot test")
gv = pw
layout_ = pg.GraphicsLayout()
gv.setCentralItem(layout_)
gv.show()
layout = layout_.addLayout(colspan=1)
layout.setContentsMargins(10, 10, 10, 10)
# Top row: title
layout.addLabel('title', colspan=2)
# Next row: main plot with y axis label
layout.nextRow()
layout.addLabel('y1', angle=-90, rowspan=1)
p1 = layout.addPlot()
# Next row: secondary plot
layout.nextRow()
layout.addLabel('y2', angle=-90, rowspan=1)
p2 = layout.addPlot()
# Bottom row: X axis label
layout.nextRow()
layout.addLabel("x", col=1, colspan=1)
# Share X axes
p2.setXLink(p1)
# Add data to plot ---------
p1.plot(x, y1, pen=pg.mkPen((255, 0, 0, 255), width=3))
p2.plot(x, y2, pen=pg.mkPen((0, 0, 255, 255), width=3))
# Start Qt event loop to keep the window open
if __name__ == '__main__':
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
app.exec_() # Start QApplication event loop ***
from pyqtgraph import QtGui, QtCore
import pyqtgraph as pg
import numpy as np
import sys
# Make up some data ----------
x = np.linspace(0, 80, 81)
y1 = np.sqrt(x)
y2 = 10*x**2
# Set up the plot ----------
# Switch to using white background and black foreground
# pg.setConfigOption('background', 'w')
# pg.setConfigOption('foreground', 'k')
app = QtGui.QApplication([])
pw = pg.GraphicsWindow(title="plot test")
gv = pw
layout_ = pg.GraphicsLayout()
gv.setCentralItem(layout_)
gv.show()
layout = layout_.addLayout(colspan=1)
layout.setContentsMargins(10, 10, 10, 10)
# Top row: title
layout.addLabel('title', colspan=2)
# Next row: main plot with y axis label
layout.nextRow()
layout.addLabel('y1', angle=-90, rowspan=1)
p1 = layout.addPlot()
# Next row: secondary plot
layout.nextRow()
layout.addLabel('y2', angle=-90, rowspan=1)
p2 = layout.addPlot()
# Bottom row: X axis label
layout.nextRow()
layout.addLabel("x", col=1, colspan=1)
# Share X axes
p2.setXLink(p1)
p1.getAxis('left').setWidth(int(100))
p2.getAxis('left').setWidth(int(100))
# Add data to plot ---------
p1.plot(x, y1, pen=pg.mkPen((255, 0, 0, 255), width=3))
p2.plot(x, y2, pen=pg.mkPen((0, 0, 255, 255), width=3))
# Start Qt event loop to keep the window open
if __name__ == '__main__':
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
app.exec_() # Start QApplication event loop ***
只需将“左”轴链接到已注册的视图即可。 比如:
Widths = [i.width() for i in xAxis]
maximum=Widths.index(max(Widths))
viewBox[maximum].register('largest')
for i in listPlots:
i.getAxis('left').linkToView(viewBox[maximum])
其中listPlots是plotDataItems的列表
尽管过了几年,也许人们可以扩展 André 的示例来链接轴项目本身。
考虑到示例中的布局,可能会产生以下效果。
from itertools import chain
# iterate though all items of the layout,
# linking the left axis of all items 1...
# to the ViewBox of the first item, 0
items_iter = chain(layout.items.keys())
first = next(items_iter)
first_vb = first.getViewBox()
for nxt in items_iter:
nxt.getAxis('left').linkToView(first_vb)
这可能有助于对齐项目的实际“视图区域”(?),对于沿“左”轴的刻度字符串中具有相似内容的轴项目。
已知限制:
layout
。如果布局使用多列,迭代器还可以对 layout.items
映射为了解决这些限制,可以调整轴项目本身的几何形状,以与沿 GraphicsLayout 给定维度的某些项目的“最远位置”对齐。当然,这可能应该链接到 Qt 中某种形式的信号处理,以便在窗口几何形状发生变化或任何项目的视图框可以调整大小后重新调整几何形状。
“链接轴到视图框”的方法可能更简洁?