kivy / kivy-ios

Toolchain for compiling Python / Kivy / other libraries for iOS
https://kivy.org/docs/guide/packaging-ios.html
MIT License
758 stars 236 forks source link

Matplotlib gets app freezing while uploading on phone #903

Open causeri3 opened 3 months ago

causeri3 commented 3 months ago

I can't get kivy running on my ios device with matplotlib. It freezes on my phone while I see the uploading screen.

MRE

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.graphics.texture import Texture
from kivy.graphics import Rectangle
import os
import numpy as np

class MatplotlibWidget(Widget):
    def __init__(self, **kwargs):
        super(MatplotlibWidget, self).__init__(**kwargs)

        app = App.get_running_app()
        os.environ['MPLCONFIGDIR'] = app.user_data_dir
        import matplotlib.pyplot as plt

        x = np.linspace(0, 10, 100)
        y = np.sin(x)

        fig, ax = plt.subplots()
        ax.plot(x, y, label='sin(x)')
        ax.set_xlabel('x')
        ax.set_ylabel('sin(x)')

        self.temp_file = os.path.join(app.user_data_dir, 'temp_plot.png')
        fig.savefig(self.temp_file)

        texture = Texture.create(size=(fig.get_figwidth() * 100, fig.get_figheight() * 100))
        texture.flip_vertical()
        texture.blit_buffer(fig.canvas.tostring_rgb(), colorfmt='rgb', bufferfmt='ubyte')

        with self.canvas:
            Rectangle(texture=texture, size=(fig.get_figwidth() * 100, fig.get_figheight() * 100), pos=self.pos)

        plt.close(fig)

class MatplotlibApp(App):

    def build(self):
        print("app.directory = ", self.directory)
        print("app.user_data_dir = ", self.user_data_dir)
        layout = BoxLayout()

        layout.add_widget(MatplotlibWidget())

        return layout

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

My setup

Running

brew install autoconf automake libtool pkg-config
brew link libtool
pip3 install Cython==3.0.0
toolchain build kivy
toolchain build matplotlib
toolchain create mat matplot-kivy-test
toolchain update mat-ios

XCode gives me:

Available orientation: KIVY_ORIENTATION=LandscapeLeft LandscapeRight Portrait PortraitUpsideDown Initializing python

:1: DeprecationWarning: the imp module is deprecated in favour of importlib and slated for removal in Python 3.12; see the module's documentation for alternative uses Running main.py: /private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/YourApp/main.pyc [INFO ] [Logger ] Record log in /private/var/mobile/Containers/Data/Application/6274477B-265C-402E-B79F-9FCDEE0EA66F/Documents/.kivy/logs/kivy_24-03-25_7.txt [INFO ] [Kivy ] v2.3.0 [INFO ] [Kivy ] Installed at "/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/kivy/__init__.py" [INFO ] [Python ] v3.11.6 (main, Mar 25 2024, 09:45:57) [Clang 15.0.0 (clang-1500.1.0.2.5)] [INFO ] [Python ] Interpreter at "/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/mat" [INFO ] [Logger ] Purge log fired. Processing... [INFO ] [Logger ] Purge finished! [INFO ] [Factory ] 195 symbols loaded [INFO ] [Image ] Providers: img_imageio, img_tex, img_sdl2 (img_dds, img_ffpyplayer, img_pil ignored) app.directory = /private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/YourApp app.user_data_dir = /private/var/mobile/Containers/Data/Application/6274477B-265C-402E-B79F-9FCDEE0EA66F/Documents/matplotlib [INFO ] [Window ] Provider: sdl2 You need UIApplicationSupportsIndirectInputEvents in your Info.plist for mouse support [INFO ] [GL ] Using the "OpenGL ES 2" graphics system [INFO ] [GL ] Backend used [INFO ] [GL ] OpenGL version [INFO ] [GL ] OpenGL vendor [INFO ] [GL ] OpenGL renderer [INFO ] [GL ] OpenGL parsed version: 2, 0 [INFO ] [GL ] Shading version [INFO ] [GL ] Texture max size <4096> [INFO ] [GL ] Texture max units <8> [INFO ] [Window ] auto add sdl2 input provider [INFO ] [Window ] virtual keyboard not allowed, single mode, not docked [DEBUG ] [matplotlib data path] /private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data [DEBUG ] CONFIGDIR=/private/var/mobile/Containers/Data/Application/6274477B-265C-402E-B79F-9FCDEE0EA66F/Documents/matplotlib [DEBUG ] interactive is False [DEBUG ] platform is ios [DEBUG ] CACHEDIR=/private/var/mobile/Containers/Data/Application/6274477B-265C-402E-B79F-9FCDEE0EA66F/Documents/matplotlib [DEBUG ] Using fontManager instance from /private/var/mobile/Containers/Data/Application/6274477B-265C-402E-B79F-9FCDEE0EA66F/Documents/matplotlib/fontlist-v330.json [DEBUG ] Loaded backend agg version v2.2. [DEBUG ] [findfont ] Matching sans\-serif:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0. [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf', name='DejaVu Serif', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttf', name='STIXSizeOneSym', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 10.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf', name='DejaVu Serif', style='italic', variant='normal', weight=400, stretch='normal', size='scalable')) = 11.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf', name='STIXSizeTwoSym', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 10.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttf', name='STIXNonUnicode', style='italic', variant='normal', weight=700, stretch='normal', size='scalable')) = 11.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf', name='STIXGeneral', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttf', name='STIXSizeFourSym', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf', name='STIXSizeFiveSym', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/cmr10.ttf', name='cmr10', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf', name='STIXSizeThreeSym', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf', name='STIXSizeThreeSym', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 10.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf', name='DejaVu Sans', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 0.33499999999999996 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf', name='DejaVu Sans Mono', style='oblique', variant='normal', weight=400, stretch='normal', size='scalable')) = 11.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf', name='STIXSizeOneSym', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf', name='STIXSizeTwoSym', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf', name='DejaVu Sans Mono', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 10.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf', name='DejaVu Sans Mono', style='oblique', variant='normal', weight=700, stretch='normal', size='scalable')) = 11.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf', name='DejaVu Sans Mono', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf', name='DejaVu Serif', style='italic', variant='normal', weight=700, stretch='normal', size='scalable')) = 11.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/cmss10.ttf', name='cmss10', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf', name='cmmi10', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/cmex10.ttf', name='cmex10', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/cmtt10.ttf', name='cmtt10', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttf', name='STIXSizeFourSym', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 10.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf', name='DejaVu Sans', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 0.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttf', name='STIXNonUnicode', style='italic', variant='normal', weight=400, stretch='normal', size='scalable')) = 11.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttf', name='STIXNonUnicode', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 10.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf', name='DejaVu Serif', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 10.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf', name='cmsy10', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf', name='STIXGeneral', style='italic', variant='normal', weight=700, stretch='normal', size='scalable')) = 11.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf', name='DejaVu Sans', style='oblique', variant='normal', weight=400, stretch='normal', size='scalable')) = 1.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf', name='STIXGeneral', style='normal', variant='normal', weight=700, stretch='normal', size='scalable')) = 10.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf', name='DejaVu Sans', style='oblique', variant='normal', weight=700, stretch='normal', size='scalable')) = 1.335 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf', name='STIXGeneral', style='italic', variant='normal', weight=400, stretch='normal', size='scalable')) = 11.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttf', name='DejaVu Sans Display', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttf', name='STIXNonUnicode', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/cmb10.ttf', name='cmb10', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] score(FontEntry(fname='/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf', name='DejaVu Serif Display', style='normal', variant='normal', weight=400, stretch='normal', size='scalable')) = 10.05 [DEBUG ] [findfont ] Matching sans\-serif:style=normal:variant=normal:weight=normal:stretch=normal:size=10.0 to DejaVu Sans ('/private/var/containers/Bundle/Application/9BA1E625-5E54-42C1-B55F-0CBF1EE8BF8A/mat.app/lib/python3.11/site-packages/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf') with score of 0.050000.
causeri3 commented 3 months ago

@tcaduser Could you possibly share some working code you used to develop the recipe?

ComputerVision804 commented 3 months ago

Matplotlib Compatibility: Matplotlib is primarily designed for desktop environments and might not have full compatibility with iOS. Limited Graphics Acceleration: Kivy on iOS relies on OpenGL for rendering, but some features like Matplotlib plots might not be efficiently handled by the limited OpenGL support on iOS devices.

mp-007 commented 3 months ago

@causeri3 Can you try my project if it solve your issue: https://github.com/mp-007/kivy_matplotlib_widget My project used an other approach by using Agg backend. The rendering will be much faster.

You can used this working example:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
import os
import numpy as np
import matplotlib.pyplot as plt
from kivy_matplotlib_widget.uix.graph_widget import MatplotFigure

#or use this widget if you have multiple axis and not just lines
#from kivy_matplotlib_widget.uix.graph_subplot_widget import MatplotFigureSubplot

class MatplotlibApp(App):

    def build(self):
        print("app.directory = ", self.directory)
        print("app.user_data_dir = ", self.user_data_dir)
        layout = BoxLayout()

        x = np.linspace(0, 10, 100)
        y = np.sin(x)

        fig, ax = plt.subplots()
        ax.plot(x, y, label='sin(x)')
        ax.set_xlabel('x')
        ax.set_ylabel('sin(x)')

        figure_widget = MatplotFigure()
        figure_widget.figure = fig

        layout.add_widget(figure_widget)

        return layout

if __name__ == '__main__':
    MatplotlibApp().run()
tcaduser commented 3 months ago

Can you run with the xcode debugger attached to your iphone and see if it crashes in the c code. I haven't worked with this recently, but I have had issues where I have needed to compile multiple times to get the code in a good state. I think there may be some caching issue between the IOS phone and phone simulator builds.

tcaduser commented 3 months ago

Please see here for a brief description of what I am encountering.

https://github.com/kivy/kivy-ios/issues/865

causeri3 commented 3 months ago

Will try later, right now https://download.savannah.gnu.org seems to be down.

causeri3 commented 2 months ago

Tbh, I gave up on matplotlib and visualize the data simplified with kivy widgets. The old XCode debugging logs from the build on my iPhone are above. For the moment, I keep on struggeling to get the App on TestFlight.