私はPyQt(pyqtgraph)のラッパーを使ってGUIアプリケーションを構築しています。 MatplotlibWidgetを使用してSeabornプロットを埋め込みたいとします。しかし、私の問題は、FacetGrid
のようなSeabornラッパーメソッドは外部のFigureハンドルを受け入れないということです。さらに、FacetGrid
によって生成された図形(.fig
)の基礎となるMatplotlibWidgetオブジェクトを更新しようとすると、機能しません(draw
の後のプロットなし)。回避策の提案はありますか?PyQt(pyqtgraph)に "Figure Type" Seaborn Plotを埋め込む
答えて
SeabornのFacetgrid
は、pandasデータフレームをmatplotlib pyplotインターフェイスにすばやく接続する便利な機能を提供します。
しかし、GUIアプリケーションでは、pyplotではなくmatplotlib APIを使用することはめったにありません。
ここで直面している問題は、Facetgrid
が既に独自のmatplotlib.figure.Figure
オブジェクト(Facetgrid.fig
)を作成していることです。また、MatplotlibWidget は独自の図形を作成するので、2つの図形になります。
さて、少しバックステップしてみましょう: 原理的には、最初のプロットを作成し、図のキャンバス(matplotlib.backends.backend_qt4agg.FigureCanvasQTAgg
)に得られた数値を提供することで、PyQtは中seaborn Facetgrid
プロットを使用することが可能です。以下は、その方法の例です。
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import sys
import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")
def seabornplot():
g = sns.FacetGrid(tips, col="sex", hue="time", palette="Set1",
hue_order=["Dinner", "Lunch"])
g.map(plt.scatter, "total_bill", "tip", edgecolor="w")
return g.fig
class MainWindow(QtGui.QMainWindow):
send_fig = QtCore.pyqtSignal(str)
def __init__(self):
super(MainWindow, self).__init__()
self.main_widget = QtGui.QWidget(self)
self.fig = seabornplot()
self.canvas = FigureCanvas(self.fig)
self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
self.canvas.updateGeometry()
self.button = QtGui.QPushButton("Button")
self.label = QtGui.QLabel("A plot:")
self.layout = QtGui.QGridLayout(self.main_widget)
self.layout.addWidget(self.button)
self.layout.addWidget(self.label)
self.layout.addWidget(self.canvas)
self.setCentralWidget(self.main_widget)
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
win = MainWindow()
sys.exit(app.exec_())
これはうまく動作しますが、これはまったく役に立ちますが、疑問があります。ほとんどの場合、GUI内にプロットを作成することは、ユーザーのやりとりに応じて更新されることを目的としています。上の例の場合、新しい図形インスタンスを作成し、この図形で新しいキャンバスを作成し、古いキャンバスインスタンスを新しいキャンバスインスタンスに置き換えてレイアウトに追加する必要があるので、これはかなり非効率的です。このproblematicsはlmplot
、factorplot
、jointplot
、FacetGrid
およびおそらく他のような、図形レベルで動作seabornのものプロット関数、に特異的であること
注意。
regplot
,boxplot
,kdeplot
のような他の関数は、軸レベルで動作し、matplotlib axes
オブジェクトを引数(sns.regplot(x, y, ax=ax1)
)として受け入れます。
possibile溶液最初pandas plotting functionalityを使用して、例えば、それらの軸にサブプロット軸と後プロットを作成することです。
df.plot(kind="scatter", x=..., y=..., ax=...)
ここで、ax
は、以前に作成された軸に設定する必要があります。
これにより、GUI内のプロットを更新できます。以下の例を参照してください。もちろん、通常のマットプロットライブプロット(ax.plot(x,y)
)または上記海底軸レベル関数の使用も同様に機能します。
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import sys
import seaborn as sns
tips = sns.load_dataset("tips")
class MainWindow(QtGui.QMainWindow):
send_fig = QtCore.pyqtSignal(str)
def __init__(self):
super(MainWindow, self).__init__()
self.main_widget = QtGui.QWidget(self)
self.fig = Figure()
self.ax1 = self.fig.add_subplot(121)
self.ax2 = self.fig.add_subplot(122, sharex=self.ax1, sharey=self.ax1)
self.axes=[self.ax1, self.ax2]
self.canvas = FigureCanvas(self.fig)
self.canvas.setSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
self.canvas.updateGeometry()
self.dropdown1 = QtGui.QComboBox()
self.dropdown1.addItems(["sex", "time", "smoker"])
self.dropdown2 = QtGui.QComboBox()
self.dropdown2.addItems(["sex", "time", "smoker", "day"])
self.dropdown2.setCurrentIndex(2)
self.dropdown1.currentIndexChanged.connect(self.update)
self.dropdown2.currentIndexChanged.connect(self.update)
self.label = QtGui.QLabel("A plot:")
self.layout = QtGui.QGridLayout(self.main_widget)
self.layout.addWidget(QtGui.QLabel("Select category for subplots"))
self.layout.addWidget(self.dropdown1)
self.layout.addWidget(QtGui.QLabel("Select category for markers"))
self.layout.addWidget(self.dropdown2)
self.layout.addWidget(self.canvas)
self.setCentralWidget(self.main_widget)
self.show()
self.update()
def update(self):
colors=["b", "r", "g", "y", "k", "c"]
self.ax1.clear()
self.ax2.clear()
cat1 = self.dropdown1.currentText()
cat2 = self.dropdown2.currentText()
print cat1, cat2
for i, value in enumerate(tips[cat1].unique().get_values()):
print "value ", value
df = tips.loc[tips[cat1] == value]
self.axes[i].set_title(cat1 + ": " + value)
for j, value2 in enumerate(df[cat2].unique().get_values()):
print "value2 ", value2
df.loc[ tips[cat2] == value2 ].plot(kind="scatter", x="total_bill", y="tip",
ax=self.axes[i], c=colors[j], label=value2)
self.axes[i].legend()
self.fig.canvas.draw_idle()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
win = MainWindow()
sys.exit(app.exec_())
最終単語について pyqtgraph:私はpyqtgraph PyQtは用のラッパーが、より多くの拡張子を呼び出すことはありません。pyqtgraphには独自のQt(ポータブルで自由に動作する)が付属していますが、Pyqt内で使用できるパッケージでもあります。そのため、同じことが MatplotlibWidget(
mw = pg.MatplotlibWidget()
)についても同様で、単に
self.pgcanvas = pg.GraphicsLayoutWidget()
self.layout().addWidget(self.pgcanvas)
でPyQtはレイアウトにGraphicsLayoutWidget
を追加することができます。この種のウィジェットを使用することはできますが、これは便利なラッパーにすぎません。なぜなら、正しいmatplotlibのインポートを見つけ、Figure
とFigureCanvas
というインスタンスを作成するだけだからです。他のpyqtgraph機能を使用していない限り、完全なpyqtgraphパッケージをインポートするだけで、5行のコードを保存することができます。
これは徹底的で良い回答ですが、最初の文章は正確ではありません。 – mwaskom
@mwaskom私が間違っている場合は、私を修正してください。便利な関数ではない場合、 'FacetGrid'と呼べるものは何ですか? – ImportanceOfBeingErnest
初心者のために、それはクラスであり、関数ではありません。 – mwaskom
- 1. pyqtgraphをenamlに埋め込む方法は?
- 2. python - PyQtアプリケーションにMatplolib/Basemapを埋め込む
- 3. PyQtに埋め込まれたMatplotlibインタラクティブグラフ
- 4. pyqt GUIに埋め込まれたmatplotlibウィジェットでFigureCanvasをFigure全体に埋め込む方法を教えてください。
- 5. VisQグラフをPyQtに埋め込む方法は?
- 6. heroku appにbokehを埋め込む
- 7. PyQt5のグラフィックスを埋め込む
- 8. ベクトルプロットをTkinterに埋め込む
- 9. symfony 2フォーム、埋め込みコレクションにコレクションを埋め込む
- 10. Mailchimp CSSを埋め込む
- 11. matplotとseaborn figureパラメータ/カスタマイズ
- 12. wxPythonウィンドウにPyQt4ウィジェットを埋め込む
- 13. matplotlibをPyQt4に埋め込む
- 14. html5ビデオプレイヤースクリプトで埋め込まれたfacebookを埋め込む
- 15. 埋め込みyoutubeをc/gtkアプリケーションに埋め込む
- 16. 埋め込みウェブページにExcelを埋め込む
- 17. PyQtアプリケーションにC++ウィジェットを埋め込むことは可能ですか?
- 18. MatplotlibグラフをUIに埋め込むPyQt5
- 19. YouTubeチャンネルサイドバーに埋め込む?
- 20. jQueryモバイルページにGoogleマップを埋め込む
- 21. フォームを動的に埋め込む
- 22. HTMLページにswfファイルを埋め込む
- 23. SpiderMonkey JSを埋め込む
- 24. Flash Playerを埋め込む
- 25. ツイートを埋め込む
- 26. CSSスタイルを埋め込む?
- 27. bugzillaレポートを埋め込む
- 28. Pythonスクリプトを埋め込む
- 29. wav as3を埋め込む
- 30. Javaアプレットを埋め込む
この問題は本当にpyqtgraphのMatplotlibWidgetに関連していますか、通常のmatplotlibプロット内で同じ方法で発生しますか? 「図形(.fig)のMatplotlibWidgetオブジェクトをFacetGridによって生成された図形で更新しようとすると」という意味を指定できますか?あなたは人物で人物をどのように更新しますか?これを試みるコードを表示できますか? – ImportanceOfBeingErnest