私はwxPythonでmatplotlibの図を埋め込んだGUIを書いています。 Figureの背景色を(かなり大きい)GUIの残りの部分と同じにしたい。残念なことに、GUIの正確な色はOSに依存しているため、固定の背景色を設定するだけでは不十分です。これはOSによって変わるためです。したがって、matplotlib-figureを作成するときにfacecolor='none'
を使用しようとしました。しかし、予期せぬ問題が発生しました(下の画像を参照):キャンバスを再描画するたびに、フォントの重量が変化しているかのように、ラベルテキストと目盛りが太くなります。私はthis three years old questionを見つけました。これは非常によく似た問題を扱うようですが、解決策や対処方法はありません。これはmatplotlib/wxpythonの意図された機能か、まだ修正されていないばかりのバグですか?透明なmatplotlibフィギュアキャンバスをwxに埋め込む
問題を示すコード例。私は2つのFigureCanvasesを作成します。最初のものはfacecolor='b
のバックグラウンドを持ち、キャンバスを再描画するときにテキストが太くなっていません。 2番目のキャンバスはfacecolor='none'
を使用しており、キャンバスの再描画ごとに太く太いテキストが表示されます。
import wx
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
class MyCanvas(wx.Panel):
def __init__(self, parent, col):
wx.Panel.__init__(self, parent, id=-1)
self.fig = Figure(figsize=(1, 1), edgecolor='k', facecolor=col)
self.ax = self.fig.add_subplot(1, 1, 1)
self.ax.set_ylabel('Label')
self.fig.subplots_adjust(left=0.5)
self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
szr_ctr = wx.BoxSizer(wx.VERTICAL)
szr_ctr.Add(self.canvas, 1, wx.ALL | wx.GROW)
self.SetSizerAndFit(szr_ctr)
wx.CallAfter(self.canvas.draw)
class wind(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent)
self.i = 0
figsizer = wx.BoxSizer(wx.HORIZONTAL)
self.canvas1 = MyCanvas(self, col='b')
figsizer.Add(self.canvas1, 1, wx.GROW | wx.ALL)
self.canvas2 = MyCanvas(self, col='none')
figsizer.Add(self.canvas2, 1, wx.GROW | wx.ALL)
button = wx.Button(self, wx.ID_CLOSE, "Press me")
button.Bind(wx.EVT_BUTTON, self.on_button)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(figsizer, 1, wx.ALL | wx.GROW, 10)
sizer.Add(button, 0, wx.ALL, 10)
self.SetSizer(sizer)
self.Layout()
self.Show()
def on_button(self, event):
wx.CallAfter(self.canvas1.canvas.draw)
wx.CallAfter(self.canvas2.canvas.draw)
if __name__ == '__main__':
wxapp = wx.App(redirect=False)
v = wind(None, "Fig")
wxapp.MainLoop()
青い背景の図は、期待通りに機能します。 none
の図は、いくつかのキャンバスの再描画後に、より厚くて厚いテキストと軸線を取得します。
編集
(以下)に再描画機能を変更するキャンバスが正しく再描画されていない問題を解決します。
def on_button(self, event):
wx.CallAfter(self.canvas1.canvas.draw)
wx.CallAfter(self.canvas2.canvas.draw)
wx.CallAfter(self.canvas1.Refresh) # <-----------
wx.CallAfter(self.canvas2.Refresh) # <-----------