holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.67k stars 508 forks source link

Make it really easy to get inspired and get started with Panel #2803

Open MarcSkovMadsen opened 2 years ago

MarcSkovMadsen commented 2 years ago

Why

Looking at the home page of Panel at https://panel.holoviz.org/ I think it can be difficult for new users to really get inspired and to quickly start out. And that is a pity as the framework is now very useable, flexible and very powerful. It's the best.

https://user-images.githubusercontent.com/42288570/136146069-fb6051c1-6c86-4f5b-8e3e-7192cbc724f8.mp4

Guiding Basic Principles

I believe the guiding principles should be

Issues

Suggestions

Gif Intro

At the top you would need some kind of simple video that shows the basic principles and looks. Potential Users will spend 30 secs evaluating Panel and potentially leave if they do not understand it.

https://user-images.githubusercontent.com/42288570/136147211-a1366a84-ca72-4b0a-a7f4-b6254e76dd2a.mp4

There could be a link to the best in-depth Panel video tutorial and some blog post describing the vision of Panel.

Short installation instructions

The content below is Ok but it could be more visually appealing by using better colors.

image

or something that looks interactive

https://user-images.githubusercontent.com/42288570/136148976-9064abbc-59fb-4b5a-bfac-facf6abdb1ab.mp4

Working Example

One end to end example that provides something interesting, nice looking, can be copy pasted and used as a starting point for the users own application. Should include gif and link to video walk through of example.

We can create something even more inspiring than the below

image

Link to Getting started tutorial.

Gallery of Examples

image

These examples are ok but there should be many more across different domains and use cases there should be some kind of "movement" catching the attention. It could be gifs or just the images/ links changing on some schedule.

It's also important that the examples use different colors (not only green) so that they can be used in users contexts.

And eventually something about "for more check out the gallery https://panel.holoviz.org/gallery/index.html# and the live gallery apps at https://panel-gallery.pyviz.demo.anaconda.com". You also link to the awesome-panel awesome list to check out https://awesome-panel.org/awesome-list alternative community resources.

Link to cheatsheet

image

(Re-)Move

Declarative, reactive programming

Interesting, but no beginner understands this and why its important. Move away from front page

image

Usage environments

Interesting. But too much info. Move away from home page and link to it instead.

image

Inspiration

TO BE UPDATED FROM DISCUSSION BELOW.

maximlt commented 2 years ago

Hey Marc, I tend to agree with you, a nicer landing page wouldn't hurt :)

MarcSkovMadsen commented 2 years ago

Thanks. @maximlt. Regarding the Intro Video I don't think we have the resources to create a similarly professional looking video. But I think a video like the below that demonstrates the general principles like pn.bind/ pn.depends, pn.widgets, pn.layouts, pn.pane, pn.template, panel serve could be used.

https://user-images.githubusercontent.com/42288570/136175372-eaadd64a-94ac-4031-8a20-922d417a8030.mp4

And maybe there could be 2 or 3 of these videos. One with VS Code or some other modern IDE as well.

https://user-images.githubusercontent.com/42288570/136177900-f9f5618d-452e-4ba7-ba9a-aa91da97978e.mp4

I think a video like the below also clearly communicates the potential.

linked-brushing-2662-speedup

MarcSkovMadsen commented 2 years ago

I am up for trying to contribute something. But it would be so nice to get some suggestions and directions from the community including a diverse set of beginners.

MarcSkovMadsen commented 2 years ago

Regarding the DS/ ML comment. As I see it Panel currently appeals more to "traditional science" people and not so much to the DS/ ML space. I believe it should as it has huge potential there. And a lot of people in that space can be helped by Panel. But the alternative is to say that Panels competitive edge is "traditional science"/ "big/ complex" and focus on making it the best for that use case.

nghenzi commented 2 years ago

From my experience, It took me a while to learn to use panel and get it to work ok. In that moment, I had to keep learning it, because it was the unique option which supports to use matplotlib in a application. But in other case, I would have let of using panel.

If you check it flask, fastapi, streamlit, etc, the first example is the hello world, which in panel it would be something like

import panel as pn
def app():
    return pn.panel('# Hello World')
pn.serve(app)

In this way, with 4 lines, you have somehing working really fast. Or maybe something similarly short with interactive, but easy to understand and run it with python main.py. This together with a short resume of the panel advantages, it should be enough for a landing page. I coincide now it is overwhelming when you check the panel page.

arifin-chemist89 commented 2 years ago

Some of my experiences to use Panel:

  1. My journey with Panel was started with the Reference Gallery, as I was looked for the "parts" for the apps. I think it is important to promote this site more since it is really visually attractive, easy to understand, and more importantly it covers very wide user cases.

  2. As my app growing, the other documentations becomes important, such as Deploy and Export or Authentication, but it is true that it takes time to dig in to the details. The beginner user could be easily overwhelmed with this documentations.

  3. On the other hand, the Discourse helps me a lot to grow. I strongly recommended to advertise more the society.

  4. The recent Custom Components really keep me stick with Panel. I think there are a lot more user cases that need to be covered and this customization helps the users to explore and use Panel more.

Simple things work best and really agree with @nghenzi comment above, simple app + promotion of the panel advantages. Honestly speaking, "Panel" name is too general and not easy to find it quickly, compare to other packages.

ahuang11 commented 2 years ago

Thanks. @maximlt. Regarding the Intro Video I don't think we have the resources to create a similarly professional looking video. But I think a video like the below that demonstrates the general principles like pn.bind/ pn.depends, pn.widgets, pn.layouts, pn.pane, pn.template, panel serve could be used.

penguins_jlab_720p_fast.1.mp4 And maybe there could be 2 or 3 of these videos. One with VS Code or some other modern IDE as well.

autoreload.mp4 I think a video like the below also clearly communicates the potential.

linked-brushing-2662-speedup

The first video looks pretty good, but it looks more like an advertisement for hvplot than panel. It would be nice to show @pn.depends or pn.interact. One suggestion is to zoom in on the browser (200%?) so the text is more readable. And maybe instead of a video make a GIF so it auto-plays upon visiting.

I like the second video, but I don't think typing "AWESOME" is necessary xD

The last video to me is confusing; especially the mouse movement since it moves so fast.

Perhaps could also show how panel outshines streamlit in some aspect, perhaps like the support for all kinds of input (but I don't know because I never used streamlit).

MarcSkovMadsen commented 2 years ago

Thanks.

One comment for @nghenzi . For me the Zen of Panel would say:

Simply because 1) I have seen a lot of beginners problematically instantiating objects that are shared across sessions, they don't understand why and need help 2) Using panel serve is assumed in lots of places in the documentation 3) panel serve always seems to be a bit ahead of pn.serve with respect to options.

I would more thing to the Zen of Panel:

I really, really like the Parameterized, class based approach and use it all the time. But again I have just seen beginners have a very hard time as in addition to learning Panel they have to learn about Classes and a bit about object oriented programming.

The pn.bind based approach naturally leads to a separation between non-panel code (matplotlib, bokeh, plotly etc.) and Panel code which will help users make more maintainable code. And its also a great way to get started if you have some existing code you want to make interactive. You can do so with pn.bind. I would like pn.bind to work as a decorator too and replace pn.depends. I believe it should be technically possible.

MarcSkovMadsen commented 2 years ago

Regarding videos, I think we can actually use Panel to make something beautiful :-)

https://user-images.githubusercontent.com/42288570/136710772-eecbe21b-4b26-4501-86fe-869b81af408a.mp4

seaborn-speedup

import panel as pn
import param

pn.config.raw_css.append("""
body {
    background: "#6082A2";
    margin: 0px;
}
""")
pn.extension(sizing_mode="stretch_width")

SVG = """
<svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg>
"""

class CodeTyper(pn.viewable.Viewer):
    value = param.String()
    command = param.String()
    language = param.String(default="python")
    theme=param.String(default="tomorrow_night")
    frequency= param.Integer(default=60)
    height=param.Integer(650)

    def __init__(self, **params):
        super().__init__(**params)

        self._ace = pn.widgets.Ace(language=self.language, theme=self.theme, height=self.height, margin=0)
        self._terminal = pn.pane.Markdown("$ ", margin=(0,25), background="#25282c", style={"color": "white"}, height=75)
        self._layout = pn.Column(
            pn.Column(
                pn.pane.Markdown("# Make Seaborn Interactive with PANEL", style={"color": "white"}),
                pn.Row(pn.pane.SVG(SVG, margin=7), pn.Spacer(), background="#25282c", height=30, margin=0),
                pn.pane.Markdown("&nbsp; &nbsp; `script.py`", background="#25282c", margin=0, style={"color": "white"}),
                self._ace,
                pn.Row(pn.Spacer()),
                pn.Column(self._terminal,background="#25282c", margin=0),
                margin=(50, 150),
            ),
            background="#6082A2",
        )

        chars = list(self.value)
        command = list(self.command)
        def typer():
            if chars:
                char = chars.pop(0)
                self._ace.value += char
            elif command:
                char = command.pop(0)
                self._terminal.object += char

        pn.state.onload(lambda: pn.state.add_periodic_callback(typer, period=75))

    def __panel__(self):
        return self._layout

SCRIPT = """\
import seaborn as sns

sns.set_style("whitegrid")
penguins = sns.load_dataset("penguins")

def func(input="green"):
    plot = sns.displot(penguins, x="flipper_length_mm", color=input, legend=False)
    fig0 = plot.fig
    fig0.set_size_inches(11, 8)
    return fig0

import panel as pn

pn.extension()

select = pn.widgets.Select(value="#6082A2", options=["#a2a160", "#6082A2", "#a26061"])

interactive_func=pn.bind(func, input=select)

pn.template.FastListTemplate(
    site="Panel", title="Works With The Tools You Know And Love",
    sidebar=[select], main=[interactive_func],
    header_background="#6082A2", accent_base_color="#6082A2"
).servable()"""

COMMAND="""
panel serve script.py --autoreload --show

Panel app running at: http://localhost:5006/panel
"""

CodeTyper(value=SCRIPT, command=COMMAND).servable()
ahuang11 commented 2 years ago

On mobile, the text is a bit hard to read, but looks good!

philippjfr commented 2 years ago

Thanks everyone for the great discussion here. I agree with all of you however I may have one other suggestion which is something we've discussed internally a few times. Specifically we were discussing having the option of creating a more marketing focused splash page for Panel distinct from the docs homepage. That of course doesn't mean we can tweak the docs page a fair bit but I'd honestly love something like the Dask homepage for Panel.

I might take a shot at a prototype this week but then I'd love to hear what you guys think should be on such a page. I'd organize it under a number of headers:

MarcSkovMadsen commented 2 years ago

I've made a few more videos to learn from. You can find the repo here https://github.com/marcskovmadsen/panel-visuals

https://user-images.githubusercontent.com/42288570/136829899-bcb23b2c-669e-472c-b299-29e398e4abf2.mp4

https://user-images.githubusercontent.com/42288570/136829917-f166215e-2608-4f53-af7a-e4d9deb4074e.mp4

jbednar commented 2 years ago

For me the Zen of Panel would say: Prefer panel serve over pn.serve

Agreed.

Prefer a function based approach over a Parameterized, class based approach.

Agreed, for intro docs, now that we have pn.bind. Parameterized is most important for someone building a library, not a one-off app, and is a tough barrier to entry. pn.bind offers a lot of the same benefits of separation between domain logic and GUI logic and of postponing bringing in any GUI code as long as possible.

Prefer pn.bind over pn.depends over pn.interact over .watch.

Agreed.

I would like pn.bind to work as a decorator too and replace pn.depends. I believe it should be technically possible.

I'm not sure what the benefit of that would be. pn.bind works well because such binding can be delayed until you are building the actual GUI, allowing you to debug and test with no GUI, lets you move such code into a Python module that doesn't depend on Panel, etc. A decorator has to be applied at the time of function definition, forcing that code to only be about GUIs and about this specific GUI, greatly limiting its flexibility going forward. Seems like a step backwards from pn.bind, at least in how I think about pn.bind vs pn.depends.

MarcSkovMadsen commented 2 years ago

Regarding pn.bind vs pn.depends. I totally buy the cons of pn.depends. I just simply want to reduce the friction by having one function supporting both use cases

@pn.bind(value=slider)
def func(value):
    pass
def func(value):
    pass

pn.bind(func, value=slider)

That would make things easier to explain. I believe it is technically possible to support.

jbednar commented 2 years ago

I'd be ok with supporting that usage, but when I last investigated, I didn't see how that syntax could be achieved by a single Python bind object; there was always an extra () required from the user somewhere. Happy to be proven wrong on that!

Note that for consistency the usage you illustrate above would differ from @pn.depends; @pn.depends creates a function of one argument which Panel then supplies in a Panel context, while @pn.bind would turn the one-argument func into a zero-argument function where value has permanently been bound to the slider's value. Such binding makes it harder to test func independently of Panel, so there are even fewer cases where a pn.bind decorator is useful than a pn.depends decorator is.

MarcSkovMadsen commented 2 years ago

A home page with some simple, nice examples is https://idom-docs.herokuapp.com/docs/index.html. It could use an easy way to find the code of the examples though.

image