posit-dev / py-shinywidgets

Render ipywidgets inside a PyShiny app
MIT License
41 stars 2 forks source link

Plotly Scatter plot height problem #122

Closed acihanckr closed 7 months ago

acihanckr commented 7 months ago

Description

When the plot height of a Plotly scatter plot set to >450, bottom of the plot cannot be seen.

What I Did

I am building a data dashboard using Plotly plots and I set the height and width of the plots using user inputs, so users can change the plot sizes. When I (unintentionally) upgraded shinywidgets from v0.2.1 to v0.2.3 I ran into an issue with the height adjustments. When user input is larger than 450, some of the plot is not visible. (I simply rolled back to v0.2.1 which fixes the problem yet I think it would be better if it can be fixed.) A simplified code to reproduce the problem is below.

from shinywidgets import output_widget, render_widget
import numpy as np
import plotly.graph_objects as go

app_ui = ui.page_fluid(
    ui.row(
        ui.column(12,
            ui.input_slider(
                    "plt_width",
                    "Plot width:",
                    min=100,
                    max=2400,
                    value=600,
                    step=50,
                ),
            ui.input_slider(
                    "plt_height",
                    "Plot height:",
                    min=100,
                    max=2400,
                    value=600,
                    step=50,
                ) 
        )
    ),
    ui.row(
        ui.column(12,
            output_widget("scatter_plot")
        )
    )
)

def server(input, output, session):
    @output
    @render_widget
    def scatter_plot():
        fig = go.Figure(go.Scatter(x = np.random.rand(1000),
                y = np.random.rand(1000), 
                mode="markers+text",
                marker={"color":"blue",
                        "size":4}))
        fig.update_layout(
            width = input.plt_width(),
            height = input.plt_height()
        )
        return fig

app = App(app_ui, server, debug=True)

enviroment is created running pipenv install with the Pipfile:

[[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi"

[packages] numpy = "1.26.2" shiny = "0.6.0" shinywidgets = "0.2.3" plotly = "5.18.0"

[dev-packages]

[requires] python_version = "3.11"

esiegel commented 7 months ago

The issue is that the default CSS provided is setting the plotly container's height to 400px always. Code for this is here. A temporary solution is to override this CSS with something like this at the top of your page.

app_ui = ui.page_fluid(
    ui.include_css("PATH_TO_MY_CSS"),
...

and the overriding css would be:

.plotly.plot-container {
  height: 100% !important;
}

All this being said, I don't think this solution is great. Ideally, the figure's layout information would lead to generated HTML with the correct sizes, but looking at the source in the repo that I linked it seems that there is confusion on how to do this:

/*
  For most/all ipywidgets, we can set these defaults via the Layout() API,
  but go.FigureWidget().layout points to plotly.js' layout, and I'm not
  sure how to get at the ipywidget's layout object from there.
*/
cpsievert commented 7 months ago

Thanks for the report! I just merged a fix in #124