Matplotlib使用OO API显示寄生轴 [英] Matplotlib show parasite axes using OO API
问题描述
我完全不知道如何使用 OO API 来使用寄生轴(图嵌入在 PyQt4 中).我想按照下面的代码从图中绘制一个轴偏移.然而,当在 PyQt4 中嵌入 matplotlib 时,不能使用 pyplot 或 host_subplot.
I am totally stumped at how to use parasite axes using the OO API (Figure embedded in PyQt4). I want to plot an axis offset from the plot as per the code below. However when embedding matplotlib in PyQt4 one can't use pyplot or host_subplot.
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)
par1 = host.twinx()
par2 = host.twinx()
offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",
axes=par2,
offset=(offset, 0))
par2.axis["right"].toggle(all=True)
host.set_xlim(0, 2)
host.set_ylim(0, 2)
par1.set_ylabel("Temperature")
par2.set_ylabel("Velocity")
p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity")
par1.set_ylim(0, 4)
par2.set_ylim(1, 65)
plt.draw()
plt.show()
我确实通过创建两个图形并按照此处的问题链接它们的轴来绘制偏移轴:
I did manage to plot an offset axis by creating two Figures and linking their axes as per the question here:
这是我的首选方法,因为它允许我在图形之间放置一个QSplitter,但是我不能让上方的图仅显示X轴-无论我设置的多小,某些图及其数据始终都可以显示y轴.
This is my preferred method as it allows me to put a QSplitter between the figures, however I cannot get the upper plot to show the X axis only - some of the graph plot and its data always show no matter how small I set the y axis to be.
然后我尝试通过获取绘图轴几何图形在单独的QWidget中绘制自己的偏移轴:
I then tried drawing my own offset axis in a separate QWidget by obtaining the plots axis geometry:
ax = foo.figure.add_subplot(1,1,1)
lineGeometry = [ax.bbox.x0, etc.]
然后使用轴几何图形用 Qt.QPainter() 在相同的开始/结束位置绘制一条线,但从单独的 QWidget 中的绘图偏移.这有点笨拙,我希望有一种更简单的方法.
then using the axis geometry to draw a line with Qt.QPainter() the same start/end position but offset from the plot in a separate QWidget. This is a bit clunky and I would prefer a simpler way.
对于使用嵌入在 Qt4 中的寄生轴的任何帮助,我们将不胜感激.
Any help with using parasitic axes embedded in Qt4 would be appreciated.
推荐答案
感谢上面提到的我之前的帖子中的评论,我设法确定您可以在 PyQt4 中使用 matplotlib.pyplot,但使用 qt4 后端进行显示.下面是一个冗长的(道歉)示例.虽然这两个图似乎都在相互叠加,但代码中有一个错误,不确定那里发生了什么:
Thanks to comments at my previous post noted above I managed to work out that you can use matplotlib.pyplot within PyQt4, but use the qt4 backend for display. A long winded (apologies) example is below. There is a bug with the code though both plots appear to be plotting on top of each other, not sure whats going on there:
import sys
from PyQt4 import QtGui, QtCore
import numpy as np
import matplotlib
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
from matplotlib.figure import Figure
class ApplicationWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.main_widget = QtGui.QWidget(self)
l = QtGui.QVBoxLayout(self.main_widget)
dc = PyPlotCanvas(self.main_widget, width=5, height=4, dpi=100)
ac = AxisArtistOO(self.main_widget, width=5, height=4, dpi=100)
l.addWidget(dc)
l.addWidget(ac)
self.main_widget.setFocus()
self.setCentralWidget(self.main_widget)
class PyPlotCanvas(FigureCanvas):
"""Matplotlib pyplot as FigureCanvas"""
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.fig.add_subplot(111)
self.compute_initial_figure()
FigureCanvas.__init__(self, self.fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self,
QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
def compute_initial_figure(self):
fig, ax = plt.subplots()
N = 3
x = np.random.rand(N)
y = np.random.rand(N)
radii = 0.1*np.random.rand(N)
patches = []
for x1,y1,r in zip(x, y, radii):
circle = Circle((x1,y1), r)
patches.append(circle)
colors = 100*np.random.rand(len(patches))
p = PatchCollection(patches, cmap=matplotlib.cm.jet, alpha=0.4)
p.set_array(np.array(colors))
ax.add_collection(p)
plt.colorbar(p)
self.fig = fig
class AxisArtistOO(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.fig.add_subplot(111)
self.compute_initial_figure()
FigureCanvas.__init__(self, self.fig)
self.setParent(parent)
FigureCanvas.setSizePolicy(self,
QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
FigureCanvas.updateGeometry(self)
def compute_initial_figure(self):
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)
par1 = host.twinx()
par2 = host.twinx()
offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",
axes=par2,
offset=(offset, 0))
par2.axis["right"].toggle(all=True)
host.set_xlim(0, 2)
host.set_ylim(0, 2)
par1.set_ylabel("Temperature")
par2.set_ylabel("Velocity")
p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity")
par1.set_ylim(0, 4)
par2.set_ylim(1, 65)
fig, ax = plt.subplots()
self.fig = fig
qApp = QtGui.QApplication(sys.argv)
aw = ApplicationWindow()
aw.show()
sys.exit(qApp.exec_())
这篇关于Matplotlib使用OO API显示寄生轴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!