I was trying to use display seaborn plot in kivy. Sometime the figure cann't fit into the MDBoxLayout. I checked the sizes of FigureCanvasKivyAgg and MDBoxLayout. But in the MDBoxLayout, the figure is not cropped. Is there a way to enable the plot to fit the MDBoxLayout automatically? Thanks in advance.
Platform: Windows 10 Python version: 3.7 Required packages:
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 code:
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()
CodePudding user response:
Seems like a bug in either matplotlib
or FigureCanvasKivyAgg
, but you may be able to work around it by using the tight_layout()
method. Try replacing the two lines:
ax.figure.set_figheight(1)
ax.figure.set_figwidth(1)
with:
ax.figure.tight_layout(pad=5)
I came up with a pad
value of 5
by trial and error.