Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matplotlib plots not rendering properly in output widgets. #11

Closed
brendan0powers opened this issue Mar 15, 2023 · 4 comments
Closed

Matplotlib plots not rendering properly in output widgets. #11

brendan0powers opened this issue Mar 15, 2023 · 4 comments

Comments

@brendan0powers
Copy link

When using an ipywidgets.Output widget in a reacton component, plots are not displayed in notebook. I've tested this with the ipympl and inline backends. It works fine when using ipywidgets directly, and used to work with react-ipywdgets 0.11.

Here's an example that shows both the working case (with ipywidgeds) and the non-working case (reacton).

import matplotlib.pyplot as plt
import reacton as react
import reacton.ipywidgets as w
import ipywidgets as widgets

#%matplotlib inline
%matplotlib ipympl

def plot(outputWidget):
    with plt.ioff():
        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')

        with outputWidget:
            print("Displaying")
            plt.show()


# Reacton Test Case
@react.component()
def Test():
    render, setRender = react.use_state(False)
    
    def displayReacton():
        if render == False:
            return
        
        outputWidget = react.get_widget(output)
        plot(outputWidget)
    
    with w.VBox() as vbox:
        w.Button(description="Render", on_click=lambda: setRender(True))
        output = w.Output()
        
    react.use_effect(displayReacton, [render])
    
    return vbox

Test()

# Ipywidgets test case
outputWidget = widgets.Output()
button = widgets.Button(description="Render")

def displayIpywidgets(_):
    plot(outputWidget)

button.on_click(displayIpywidgets)

widgets.VBox([
    button,
    outputWidget
])

Software Versions:

python                          3.10.9
matplotlib-base           3.7.1
ipympl                           0.9.3
reacton                          1.2.2
@maartenbreddels
Copy link
Contributor

Thanks for the great bug report.

Note that we now automatically capture anything in the render phase to an output widget that is using the display mechanism. E.g. you could do:

...
        ax.legend(title='Fruit color')
#         with outputWidget:
        plt.show()
...
    with w.VBox() as vbox:
        if render:
            plot(None)
        w.Button(description="Render", on_click=lambda: setRender(True))
        
#     react.use_effect(displayReacton, [render])

See https://solara.dev/api/display

@brendan0powers
Copy link
Author

Awesome! Thanks for the quick response. I've tested against master, and it seems to fix the issue. The version in conda-forge (1.3.2) still has the bug though, I assume 1.3.3 will be released soonish?

@maartenbreddels
Copy link
Contributor

merged it 10 seconds ago conda-forge/reacton-feedstock#14 :)

It can take up to an hour to be available.

@brendan0powers
Copy link
Author

Thanks! 1.3.3 from conda-forge resolves the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants