Skip to content

MatplotlibChart instance cannot be a row/column in ft.Row/ft.Column in ft.UserControl, or MatplotlibChart instance will override build() #1602

@heximing

Description

@heximing

Description
MatplotlibChart instance cannot be a row/column in ft.Row or ft.Column in ft.UserControl, or MatplotlibChart instance will override build().

Code example to reproduce the issue:

import matplotlib
import matplotlib.pyplot as plt
import flet as ft
from flet.matplotlib_chart import MatplotlibChart
import tracemalloc
tracemalloc.start()
matplotlib.use("svg")


class GreeterControl(ft.UserControl):
    def build(self):
        data_row = ft.Row(
            controls=[
                ft.Text(value="(Some Live Data here 111)", bgcolor=ft.colors.RED_300, text_align=ft.TextAlign.RIGHT),
                ft.Text(value="(Some Live Data here 222)", bgcolor=ft.colors.RED_300, text_align=ft.TextAlign.RIGHT),
                ft.Text(value="(Some Live Data here 333)", bgcolor=ft.colors.RED_300, text_align=ft.TextAlign.RIGHT),
                ft.Text(value="(Some Live Data here 444)", bgcolor=ft.colors.RED_300, text_align=ft.TextAlign.RIGHT),
            ]
        )

        # plt.close('all')
        fig, ax = plt.subplots()
        fruits = ["apple", "blueberry", "cherry", "orange"]
        counts = [40, 100, 30, 55]
        bar_labels = ["red", "blue", "_red", "orange"]
        bar_colors = ["tab:red", "tab:blue", "tab:red", "tab:orange"]
        ax.bar(fruits, counts, label=bar_labels, color=bar_colors)
        ax.set_ylabel("fruit supply")
        ax.set_title("Fruit supply by kind and color")
        ax.legend(title="Fruit color")

        chart = MatplotlibChart(figure=fig, expand=True, isolated=True, original_size=True)

        return ft.Column(
            controls=[
                data_row,
                data_row,
                chart,
                ft.ElevatedButton(text="Start (does nothing)", disabled=True)
            ],
            alignment=ft.alignment.center, horizontal_alignment=ft.CrossAxisAlignment.CENTER
        )

def main(page: ft.Page):
    page.add(
        ft.Row(controls=[ft.Text(value="(Title) *** (Title)", italic=False, selectable=False,
                                 style=ft.TextThemeStyle.DISPLAY_MEDIUM)], alignment=ft.MainAxisAlignment.CENTER),
        GreeterControl(),
        ft.Row(controls=[ft.Text(value="(Bottom) *** (Bottom)", italic=False, selectable=False,
                                 style=ft.TextThemeStyle.DISPLAY_SMALL)], alignment=ft.MainAxisAlignment.CENTER),
    )

if __name__ == '__main__':
    ft.app(target=main)
    tracemalloc.stop()

Describe the results you received:
un-expected

Describe the results you expected:
expected

Additional information you deem important (e.g. issue happens only occasionally):
in build(), in return, replacing the line chart, with

ft.Container(content=chart, margin=5, padding=5, border=ft.border.all(1, ft.colors.BLUE_500), alignment=ft.alignment.center, bgcolor=ft.colors.GREEN_300, border_radius=10),

will get the expected result. i.e. need to use a Container to wrap MatplotlibChart instance to work.

It seems like it only have problem when ft.UserControl is a ft.Row or ft.Column. If ft.UserControl is a MatplotlibChart by itself, everything works as expected. For example:

import matplotlib
import matplotlib.pyplot as plt
import flet as ft
from flet.matplotlib_chart import MatplotlibChart
import tracemalloc
tracemalloc.start()
matplotlib.use("svg")

class GreeterControl(ft.UserControl):
    def build(self):
        # plt.close('all')
        fig, ax = plt.subplots()
        fruits = ["apple", "blueberry", "cherry", "orange"]
        counts = [40, 100, 30, 55]
        bar_labels = ["red", "blue", "_red", "orange"]
        bar_colors = ["tab:red", "tab:blue", "tab:red", "tab:orange"]
        ax.bar(fruits, counts, label=bar_labels, color=bar_colors)
        ax.set_ylabel("fruit supply")
        ax.set_title("Fruit supply by kind and color")
        ax.legend(title="Fruit color")

        chart = MatplotlibChart(figure=fig, expand=True, isolated=True, original_size=True)

        return chart

def main(page: ft.Page):
    page.add(
        ft.Row(controls=[ft.Text(value="(Title) *** (Title)", italic=False, selectable=False,
                                 style=ft.TextThemeStyle.DISPLAY_MEDIUM)], alignment=ft.MainAxisAlignment.CENTER),
        GreeterControl(),
        ft.Row(controls=[ft.Text(value="(Bottom) *** (Bottom)", italic=False, selectable=False,
                                 style=ft.TextThemeStyle.DISPLAY_SMALL)], alignment=ft.MainAxisAlignment.CENTER),
    )

# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    ft.app(target=main)
    tracemalloc.stop()
    print("exiting...")

Flet version (pip show flet):
0.74

Operating system:
Windows 10, PyCharm 2023.1.2 (Community Edition), Build #PC-231.9011.38, built on May 16, 2023

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions