gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
33.82k stars 2.57k forks source link

Bokeh plots do not appear #1942

Closed abidlabs closed 1 year ago

abidlabs commented 2 years ago

Describe the bug

When using the Plot component, bokeh plots do not appear at all.

This is documented here: #1632

Pictures cannot be generated in Bokeh mode.

And in this PR: #1609

The Bokeh plots are currently broken. The reason for this is that bokehJS internally uses getElementById to get the container of the plot and render it. Since Gradio UI is using the shadow DOM to render, this step fails.

I have tried here a workaround where I added a new hidden div in the index.html file to use as a helper to render the plot, once it is rendered, then the content is appended to the actual div that should have the plot. This part is all working, unfortunately although I can see the div with the expected content, the plot is still not showing.

The PR was closed because it was an attempt to fix the problem using an older version of bokeh. We still need to find a solution using the latest version of bokeh.

Is there an existing issue for this?

Reproduction

https://github.com/gradio-app/gradio/blob/main/demo/outbreak_forecast/run.py

Screenshot

No response

Logs

N/A

System Info

3.1.3

Severity

serious, but I can work around it

abidlabs commented 2 years ago

cc @dawoodkhan82 @Ian-GL

millermuttu commented 2 years ago

Is this Bug resolved in the latest release 3.4.0?

dawoodkhan82 commented 2 years ago

Is this Bug resolved in the latest release 3.4.0?

Unfortunately not yet. It is on our radar though. Will update this issue when we do resolve this.

abidlabs commented 1 year ago

It looks like bokeh 3.0.3 is out, so it might be good to revisit this @dawoodkhan82

dawoodkhan82 commented 1 year ago

Will revisit!

giswqs commented 1 year ago

I was trying to use bokeh maps. Got an error TypeError: Model.to_json() missing 1 required positional argument: 'include_defaults'

import gradio as gr
import xyzservices.providers as xyz
from bokeh.plotting import figure
from bokeh.tile_providers import get_provider

def create_map(text):

    tile_provider = get_provider(xyz.OpenStreetMap.Mapnik)
    p = figure(x_range=(-2000000, 6000000), y_range=(-1000000, 7000000),
            x_axis_type="mercator", y_axis_type="mercator")
    p.add_tile(tile_provider)
    return p

demo = gr.Interface(
    fn=create_map,
    inputs='text',
    outputs=gr.Plot().style(),
)
demo.launch()
freddyaboulton commented 1 year ago

Will take a look @giswqs ! My guess is that the gradio library is using an outdated bokeh api that's not compatible with the bokeh version in your demo.

Mind sharing your bokeh version? As well as xyzservices? BTW what is that library?

giswqs commented 1 year ago

See the example at https://docs.bokeh.org/en/latest/docs/examples/topics/geo/tile_xyzservices.html

xyzservices is a lightweight library providing a repository of available XYZ services offering raster basemap tiles.

freddyaboulton commented 1 year ago

Thanks @giswqs ! So the issue about to_json() missing 1 required positional argument should be easy to fix but the problem about the UI not displaying the plots persists. What's more, looks like there's a big difference between bokeh 2.0 and bokeh 3.0. Might be hard to support both? If we had to choose one, would 3.0 be better?

giswqs commented 1 year ago

Yes, prefer bokeh 3.x.

freddyaboulton commented 1 year ago

@giswqs We support bokeh 2 and 3 in version 3.19.1!

giswqs commented 1 year ago

@freddyaboulton Awesome! I tried bokeh 3.x, and it works like a charm. Thank you very much.

import gradio as gr
import leafmap.bokehmap as leafmap

def test(x):
    m = leafmap.Map()
    m.add_basemap('OpenTopoMap')
    return m.figure

demo = gr.Interface(fn=test, inputs="text", outputs=gr.Plot())
demo.launch()

Peek 2023-02-21 11-22

degel007 commented 1 year ago

Please, can someone help? I don't know why I can't see any outputs.

import gradio as gr import pandas as pd import numpy as np import matplotlib.pyplot as plt import joblib %matplotlib inline

df = pd.read_csv('yf_cryptodataset_1.csv')

cryptocurrencies = df['name'].unique().tolist()

days = [1, 7, 30, 90]

def select_pred(name, duration): for i in cryptocurrencies: if name == i: for j in days: if duration == j: df_b = df.groupby(df['name']).get_group(i) x = df_b.drop(['Date','Close','name','symbol','Dividends','Stock Splits'], axis=1).values y = df_b['Close'].values t_limit = int(len(x) * 0.7) x_train = x[:t_limit] y_train = y[:t_limit] x_test = x[t_limit:] y_test = y[t_limit:] pred_data = x_test[-j:] model_fit = joblib.load(f'{i}_arimamodel.joblib') predcoin = model_fit.forecast(steps=j) result = sum(predcoin)/j plt.plot(y_test[-j:], label='Actual Prices') plt.plot(predcoin, label='Predicted Prices') plt.legend() plt.title(f'{name} {j} days prediction') plt.xlabel('Days') plt.ylabel('Price') plt.show() return str(result) return plt.show()

sys_inp = [gr.Dropdown(cryptocurrencies, label = 'Select Coin'), gr.Dropdown(days, label= 'Select Days')]

sys_out = [gr.Text(), gr.Plot()]

Interface = gr.Interface(fn = select_pred, inputs = sys_inp, outputs = sys_out)

Interface.launch()

freddyaboulton commented 1 year ago

Hi @degel007 ! I think you should return both the text and plot on the same line return str(result), fig. Also return a figure and not plot.show()

Something like this:

fig = plt.figure()
plt.plot(....)
...
return str(result), fig