如何使 Figurecanvaskivyagg 自动适应 MDBoxLayout?

How to enable Figurecanvaskivyagg fit MDBoxLayout automatically?

我试图在 kivy 中使用 display seaborn plot。有时图形无法放入 MDBoxLayout。我检查了 FigureCanvasKivyAgg 和 MDBoxLayout 的大小。但在 MDBoxLayout 中,图形未被裁剪。有没有办法让绘图自动适应 MDBoxLayout? 提前致谢。

平台:Windows10 Python版本:3.7 所需软件包:

certifi==2021.10.8
charset-normalizer==2.0.9
cycler==0.11.0
docutils==0.18.1
fonttools==4.28.3
idna==3.3
Kivy==2.0.0
kivy-deps.angle==0.3.0
kivy-deps.glew==0.3.0
kivy-deps.sdl2==0.3.1
Kivy-Garden==0.1.4
kivymd==0.104.2
kiwisolver==1.3.2
matplotlib==3.1.1
numpy==1.21.4
packaging==21.3
pandas==1.3.4
Pillow==8.4.0
Pygments==2.10.0
pyparsing==3.0.6
pypiwin32==223
python-dateutil==2.8.2
pytz==2021.3
pywin32==302
requests==2.26.0
scipy==1.7.3
seaborn==0.11.2
setuptools-scm==6.3.2
six==1.16.0
tomli==1.2.2
urllib3==1.26.7

Python代码:

import logging

from kivymd.app import MDApp
from kivy.lang import Builder
import seaborn as sns
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg
from kivymd.uix.tab import MDTabsBase
from kivymd.uix.floatlayout import MDFloatLayout


class Tab(MDFloatLayout, MDTabsBase):
    '''Class implementing content for a tab.'''
    #content_text = StringProperty("")

class MainApp(MDApp):
    def __init__(self, **kwargs):
        super(MainApp, self).__init__(**kwargs)
        self.kv = Builder.load_string('''
#CustomTab@FloatLayout+MDTabsBase:
#    
Screen: 
    MDTabs:
        Tab:
            title: "Tab 2"
            content_text: f"This is an example text for {self.title}"
                
            ScrollView:
                do_scroll_y: True
                MDGridLayout:
                    cols: 2
                    spacing: "10dp"
                    MDBoxLayout:
                        id: xxx
                        MDRaisedButton:
                            id: button4read_mtx
                            text: "Draw"
                            opposite_colors: True
                            on_release: app.plot_violin()
                            disabled: False
                        MDRaisedButton:
                            id: button4size
                            text: "Size"
                            opposite_colors: True
                            on_release: app.print_size()
                            disabled: False
                    MDBoxLayout:
                        size_hint: (0.5, None)
                        height: self.size[0]
                        id: mdbl4plot
                        orientation: "vertical"
                        #size_hint: (1,3)
                        #height: "400dp"
                        id: mdbl4plot
        Tab:
            title: "Tab 2"
''')

    def build(self):
        return self.kv
    def plot_violin(self):
        self.root.ids.mdbl4plot.clear_widgets()
        sns.set_theme(style="whitegrid")
        tips = sns.load_dataset("tips")
        ax = sns.violinplot(x="day", y="total_bill", data=tips)
        ax.figure.set_figheight(1)
        ax.figure.set_figwidth(1)
        #ax.set_autoscale_on(True)
        ax.autoscale(tight=True)
        figagg=FigureCanvasKivyAgg(ax.figure)
        print(figagg)
        #print(dir(figagg))
        logging.info("figagg size: "+str(figagg.size))
        print(figagg.size_hint)
        logging.info("mdbl4plot size: "+str(self.root.ids.mdbl4plot.size))
        self.root.ids.mdbl4plot.add_widget(figagg)
    def print_size(self):
        print("mdbl4plot size" + str(self.root.ids.mdbl4plot.size))

if __name__ == '__main__':
    MainApp().run()

似乎是 matplotlibFigureCanvasKivyAgg 中的错误,但您可以使用 tight_layout() 方法解决它。尝试替换这两行:

    ax.figure.set_figheight(1)
    ax.figure.set_figwidth(1)

与:

    ax.figure.tight_layout(pad=5)

我通过反复试验得出 pad5 值。