From 48551dff0451d2570eacb6796eb2b3325e2aee24 Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Tue, 30 Jul 2024 06:42:22 +0000 Subject: [PATCH 01/11] new user feedback --- .../api/examples/outliers_declarative.md | 37 +++++++++++++++++++ doc/getting_started/build_app.md | 6 ++- doc/getting_started/installation.md | 32 ++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/doc/explanation/api/examples/outliers_declarative.md b/doc/explanation/api/examples/outliers_declarative.md index c83ccbd03a..e68d51fed6 100644 --- a/doc/explanation/api/examples/outliers_declarative.md +++ b/doc/explanation/api/examples/outliers_declarative.md @@ -82,3 +82,40 @@ pn.Column(obj.param, obj.view) ``` To support various domains, you can create hierarchies of classes encapsulating parameters and functionality across different object families. Parameters and code can inherit across classes as needed, without depending on any specific GUI library. This approach facilitates the maintenance of large codebases, all displayable and editable with Panel, adaptable over time. For a more complex illustration, refer to the [Attractors Panel app](https://examples.holoviz.org/gallery/attractors/attractors_panel.html) ([source](https://github.com/holoviz-topics/examples/tree/main/attractors)), and explore the Panel codebase itself for extensive usage of Param throughout the codebase. + +## Serving the Notebook + +Lets finalize our app by organizing our components in a nicely styled template (`MaterialTemplate`) and mark it `.servable()` to add it to our served app: + +```python +pn.template.MaterialTemplate( + site="Panel", + title="Getting Started App", + sidebar=[obj.param], + main=[obj.view], +).servable(); # The ; is needed in the notebook to not display the template. Its not needed in a script +``` + +Save the notebook with the name `app.ipynb`. + +Finally, we'll serve the app by running the command below in a terminal: + +```bash +panel serve app.ipynb --autoreload +``` + +Now, open the app in your browser at [http://localhost:5006/app](http://localhost:5006/app). + +It should look like this: + +![Getting Started App](../../../_static/images/getting_started_app.png) + +:::{tip} + +If you prefer developing in a Python Script using an editor, you can copy the code into a file `app.py` and serve it. + +```bash +panel serve app.py --autoreload +``` + +::: diff --git a/doc/getting_started/build_app.md b/doc/getting_started/build_app.md index 91cf34b6d9..af4ed827ea 100644 --- a/doc/getting_started/build_app.md +++ b/doc/getting_started/build_app.md @@ -14,7 +14,7 @@ If you're eager to roll up your sleeves and build this app alongside us, we reco Initially, the code block outputs on this website offer limited interactivity, indicated by the golden border to the left of the output below. By clicking the play button ( ), you can activate full interactivity, marked by a green left-border. ::: -## Fetching the Data +## Configuring the Application First, let's import the necessary dependencies and define some variables: @@ -37,6 +37,8 @@ Next, we'll import the Panel JavaScript dependencies using `pn.extension(...)`. pn.extension(design="material", sizing_mode="stretch_width") ``` +## Fetching the Data + Now, let's load the [UCI ML dataset](http://archive.ics.uci.edu/dataset/357/occupancy+detection) that measured the environment in a meeting room. We'll speed up our application by caching (`@pn.cache`) the data across users: ```{pyodide} @@ -121,7 +123,7 @@ pn.template.MaterialTemplate( Save the notebook with the name `app.ipynb`. -Finally, we'll serve the app with: +Finally, we'll serve the app by running the command below in a terminal: ```bash panel serve app.ipynb --autoreload diff --git a/doc/getting_started/installation.md b/doc/getting_started/installation.md index 23706457b9..d66de5ffe6 100644 --- a/doc/getting_started/installation.md +++ b/doc/getting_started/installation.md @@ -78,6 +78,38 @@ Make sure Panel is installed in the same environment as JupyterLab/Jupyter Noteb If you plan to use Panel in a non-Jupyter notebook environment, such as Google Colab or VSCode, refer to the [relevant how-to section](../how_to/notebook/other_nb.md). ::: +## Updating Panel + +:::{important} + +Instead of updating, we recommend that you create a new virtual environment from scratch and reinstall Panel to minimize the risk of potential issues. + +::: + +We suggest updating the dependencies `param` and `bokeh` along with `panel` and `watchfiles` to reduce the likelihood of problems. + +:::::{tab-set} + +::::{tab-item} pip +:sync: pip + +```bash +pip install --upgrade panel watchfiles param bokeh +``` + +:::: + +::::{tab-item} conda +:sync: conda + +```bash +conda update panel watchfiles param bokeh +``` + +:::: + +::::: + ## Next Steps Now that you have installed Panel, let's [build a simple application](build_app.md). From c1b95d08e2364460bc66a0855d11da506bab977c Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Mon, 5 Aug 2024 13:52:51 +0000 Subject: [PATCH 02/11] enable users on JupyterHub to also use debug configuration --- doc/how_to/editor/vscode_configure.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/doc/how_to/editor/vscode_configure.md b/doc/how_to/editor/vscode_configure.md index 07cacf3a19..10ed4a740d 100644 --- a/doc/how_to/editor/vscode_configure.md +++ b/doc/how_to/editor/vscode_configure.md @@ -1,43 +1,45 @@ # Configure VS Code -This guide addresses how to configure VS Code for an efficient Panel development workflow. +This guide explains how to configure VS Code for an efficient Panel development workflow. -We assume you have +We assume you have: -- a basic understanding of [working with Python in VS Code](https://code.visualstudio.com/docs/python/python-tutorial). -- installed the VS Code [Python extension](https://github.com/Microsoft/vscode-python) +- A basic understanding of [working with Python in VS Code](https://code.visualstudio.com/docs/python/python-tutorial). +- Installed the VS Code [Python extension](https://github.com/Microsoft/vscode-python). --- ## Debugging -To learn how to use the *integrated debugger* in general check out [the official guide](https://code.visualstudio.com/docs/editor/debugging). +To learn how to use the *integrated debugger* in general, check out [the official guide](https://code.visualstudio.com/docs/editor/debugging). -To configure the integrated debugger for Panel, you will need to add a debugging configuration like the below. +To enable debugging applications with `panel serve`, you can add a `"panel serve"` debugging configuration like the one below to your VS Code debugging configuration file. -```bash +```json { "version": "0.2.0", "configurations": [ { "name": "panel serve", - "type": "python", + "type": "debugpy", "request": "launch", "program": "-m", "args": [ "panel", "serve", "${relativeFile}", + "--index", + "${fileBasenameNoExtension}", "--show" ], "console": "integratedTerminal", "justMyCode": true - }, + } ] } ``` -In use it looks like +When used, it looks like this: ![Integrated Debugging of a Panel app in VS Code](../../_static/images/vscode-integrated-debugging.png) From 695ad52ed4fe6e6bb53057d08ace32d1e4d94622 Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Tue, 6 Aug 2024 16:01:28 +0000 Subject: [PATCH 03/11] improve vs code --- .../images/vscode-no-output-try-again.png | Bin 0 -> 6272 bytes doc/how_to/editor/vscode_configure.md | 168 ++++++++++++------ 2 files changed, 110 insertions(+), 58 deletions(-) create mode 100644 doc/_static/images/vscode-no-output-try-again.png diff --git a/doc/_static/images/vscode-no-output-try-again.png b/doc/_static/images/vscode-no-output-try-again.png new file mode 100644 index 0000000000000000000000000000000000000000..502de09f996ca7b069a8a4fdcb772aabab843da5 GIT binary patch literal 6272 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 M((?r6`1$Mq1hqi+O8@`> literal 0 HcmV?d00001 diff --git a/doc/how_to/editor/vscode_configure.md b/doc/how_to/editor/vscode_configure.md index 10ed4a740d..abc00bd2d5 100644 --- a/doc/how_to/editor/vscode_configure.md +++ b/doc/how_to/editor/vscode_configure.md @@ -4,11 +4,118 @@ This guide explains how to configure VS Code for an efficient Panel development We assume you have: -- A basic understanding of [working with Python in VS Code](https://code.visualstudio.com/docs/python/python-tutorial). -- Installed the VS Code [Python extension](https://github.com/Microsoft/vscode-python). +- [x] The **latest version of VS Code installed**. +- [x] A basic understanding of [working with Python in VS Code](https://code.visualstudio.com/docs/python/python-tutorial). +- [x] Installed the **latest versions** of the VS Code extensions: + - [Python](https://github.com/Microsoft/vscode-python) + - [Jupyter](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) including [Jupyter Notebook Renderers](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter-renderers) --- +## Installation + +:::info + +For `panel` to work with the [VS Code Jupyter Extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) and [Jupyter Notebook Renderers](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter-renderers) +you need to have [`jupyter_bokeh`](https://github.com/bokeh/jupyter_bokeh) and [`ipykernel`](https://github.com/ipython/ipykernel) installed in your virtual environment. + +We strongly recommend you to install into a **new virtual environment** before starting to use Panel with in the Interactive environment. Installing `jupyter_bokeh` and `ipykernel` into an old environment can lead to problems that are hard to reproduce, understand and solve. + +::: + +Install the requirements + +:::::{tab-set} + +::::{tab-item} pip + +```bash +pip install panel watchfiles jupyter_bokeh ipykernel +``` + +:::: + +::::{tab-item} conda + +conda install -c conda-forge panel watchfiles jupyter_bokeh ipykernel + +:::: + +::::: + +You should now be able to `panel serve` your python file or notebook as usual. + +## Simple Browser + +To keep your app right next to your code while you develop, it can be super productive to use the VS Code *simple browser*. + +![Panel in VS Code simple browser](../../_static/images/vs_code_simple-browser.png) + +You can open it via the *Command Palette* + +![Panel in VS Code simple browser](../../_static/images/vs_code_simple-browser_command_palette.png) + +To make it even simpler, you can add a task to `.vscode/tasks.json` + +```json +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Open Panel in Simple Browser", + "command": "${input:openSimpleBrowser}", + "problemMatcher": [] + } + ], + "inputs": [ + { + "id": "openSimpleBrowser", + "type": "command", + "command": "simpleBrowser.show", + "args": [ + "http://localhost:5006" + ] + } + ] +} +``` + +and keybinding to `keybindings.json` + +```json +[ + { + "key": "ctrl+shift+b", + "command": "workbench.action.tasks.runTask", + "args": "Open Panel in Simple Browser" + }, +] +``` + +## Notebook and Interactive Environment + +If you have followed the [installation instructions above](#installation) and added `pn.extension()` after your python imports you should be able to use the Jupyter Interactive environment as shown below. + +![Panel in VS Code Notebook Environment](../../_static/images/vscode-notebook.png) + +### Trouble Shooting + +The support for Jupyter and Panel widgets in the interactive environment is fragile and you might experience issues. + +Below is some advice for solving the issues. If that does not work for you, try + +- closing the interactive window +- upgrading VS Code to the latest version +- upgrading the Python and Jupyter VS Code extensions to the latest versions +- creating a new virtual environment, install as [described above](#installation) +- restarting VS code. + +#### No output + +If your first output does not show, try executing the command in a new cell. Sometimes VS Code need a little time to install some javascript packages behind the scenes. + +![VS Code No Output](../../_static/images/vscode-no-output-try-again.png) + ## Debugging To learn how to use the *integrated debugger* in general, check out [the official guide](https://code.visualstudio.com/docs/editor/debugging). @@ -45,7 +152,7 @@ When used, it looks like this: ## Extensions -The following extensions will help speed up your Panel workflow +The following optional extensions can help speed up your Panel workflow - [Live Server](https://github.com/ritwickdey/vscode-live-server-plus-plus): Enables you to easily view `.html` files created using `.save()` or `panel convert`. @@ -75,61 +182,6 @@ On Windows you will need to add quotes around `${relativeFile}`, i.e. replace it When you press `CTRL+SHIFT+SPACE` you will `panel serve` your file in the terminal, if you have an open terminal. -## Notebook and Interactive Environment - -Ensure you install `jupyter_bokeh` with `pip install jupyter_bokeh` or `conda install -c bokeh jupyter_bokeh` and then enable the extension with `pn.extension()`. - -You can see a notebook in action below. - -![Panel in VS Code Notebook Environment](../../_static/images/vscode-notebook.png) - -## Simple Browser - -To keep your app right next to your code while you develop, it can be super productive to use the VS Code *simple browser*. - -![Panel in VS Code simple browser](../../_static/images/vs_code_simple-browser.png) - -You can open it via the *Command Palette* - -![Panel in VS Code simple browser](../../_static/images/vs_code_simple-browser_command_palette.png) - -To make it even simpler, you can add a task to `.vscode/tasks.json` - -```json -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Open Panel in Simple Browser", - "command": "${input:openSimpleBrowser}", - "problemMatcher": [] - } - ], - "inputs": [ - { - "id": "openSimpleBrowser", - "type": "command", - "command": "simpleBrowser.show", - "args": [ - "http://localhost:5006" - ] - } - ] -} -``` - -and keybinding to `keybindings.json` - -```json -[ - { - "key": "ctrl+shift+b", - "command": "workbench.action.tasks.runTask", - "args": "Open Panel in Simple Browser" - }, -] -``` - ## Snippets To speed up your workflow you can configure [*user defined snippets*](https://code.visualstudio.com/docs/editor/userdefinedsnippets) like these [example Panel snippets](../../_static/json/vscode-snippets-python.json). When you start typing `import panel` you will get the option to select between the snippets as shown below. From 19023c68615f28aed5c4539730df41d16d8564cb Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Tue, 6 Aug 2024 16:03:56 +0000 Subject: [PATCH 04/11] Optimize PNG images (lossless) --- .../images/vscode-no-output-try-again.png | Bin 6272 -> 4224 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/_static/images/vscode-no-output-try-again.png b/doc/_static/images/vscode-no-output-try-again.png index 502de09f996ca7b069a8a4fdcb772aabab843da5..8c00b225549bf87557278f242daf430e3178fd60 100644 GIT binary patch literal 4224 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 N;AhXzw^(z=j_i1_HVQKefL^>uf5iH zt=nfk-L-cBc4%m5XoF9mfNE%LBdec>KKoStEnGouS9e>`Q1{~+l-|8l>cM}7AN%2$ zhDIGhYvsZ=^>};iX*gO#L#JcovxS9vcu_-Rj~@8MF`uL$8K0kt9DJhrW?t~w?h!59 z9pztb>4reGx7ntED>=}Lb7iM|9*_V1(us4o-yFTZAMp9H%fA^M?=;Lb>bEZ}dS&?E zv81FgZ|)PB?D}>b3R46n6A7zzb0sd}mmW=u7N2}Ce&5hLwoHnQNv-FJ)3SLpX6i^^kf{&2C3w4t5GSBAg;W7v$m`Qo!vVC{{GqxK#V z8@)=(w9-KK;I!H6Y4(_Bwx5 zNZsedp?o9uu}SZ1)fIMoNm-t^>fKrZ1+6%G6A5PP!pIQOD|l3g({=y1>NQ=M|iFY-o5$X2Iczi1y<@q7Z0IFbcKgC6`ks>bi5U<#&HJ5AN zEh)7nS3w()kL9R(&g9T5EWSUo#bOPW(gx5EWNoZ4gb9{s*lTdEo?`3HW4j*S8>WlN!>Q7@I|W&Qbw*T7E3~1Z_l{l4V^?GD$VCukm;);bUeRfBzIQmtYhpP- zO2Jph$#(?>-|ID^_Iw#RrJQS-Q_hJa)>C%|h%~DgHkFLjISIzkiqJw?RrsXY!!j5& zV}IR4N;dwHUrWjE5YY!50^v`kn%;R#fk9axq5_uk!w@x5&UJpa3zhBB(EhA$X6x}< zRkPKHkqOa4QstXsT1hb+>L2$0@wFNczE){kJ=Q}q*Hp>9@nQ^zMU1)_QN5XMctIHy zo1&W=pOVt&LaeGFWjj|$i52y^xQFz^NtuL)f0I%I-(=@aplg1WTiy?ENogSFdfDJCfc zlM65u*u{MqZlN_b74wFC?vNp5grg%`YsW?cG1zKmvg4RnggcrwiwnB|Y8HUOr4|Bd z`piQTrLh0`-yMCSrrAA6XrGdm{(1&XLi(Cq3{oSTYij8c_yDF5)nJY?_sT0=qam57kad)H!ITCkJ_zuv)V=B1|7=f zBE`lvc%vaBWi!eP*Hl+$umiUDwo~zV8_-gSY^Xq$$G+c+#$`Yx<2Hlj3qTA;K9}rF zh%oy`tF@gM3@EffOIb@E?@KMnqvGLsFmqQ>K;X`bJLt}K$AZoql1t|tE&*R&W zGcnT>J)^>U8Z;DNBrR_}(ESOc?p6TWNm^UZgCj@7_(h{G>z9C-w}}TFsXs69%?Bs7 zk)nx~rv{cB^G%mLi9YWk`Feh3A1Ge!6DDkR{iz0?8HX()!k5mvjg!&7U8U@>Ca(2P z8Wc+FZpmxS!6iGB1A$Qt(%9SHN%q34QZ_mCic)FRsVXq&NQddL-qIb?%1C4H(X#v; z9HZ}SObw%}2y)jK%H@P0B30=8NUCxnd!I8|bM1cEBwjBe)^yWEW*m(kUUi;R8QkUpY*)3%@8Fx4MC!-pw zn%hV*eW<;PY9UAAeJ6Y~h+Ryq^^mk94T5zbf)ZUwq1O?U)k8F;fvM+!)o-+5DA(lV zD;qX|aC``+-8Y!n&}&96d(=`@n&#A&EQ6N4t9sF7t@x@G4t4i64@~2+NT+SY_N)iN zryQ0Zwa+CntBv&rMRmfHiUr=l@=uJr72NEAd45w&8ra3=UU9^Xl*n*EmAH9<`3xzI zMxwmnEjhj0%_wvG`AmZ`IM*z@_!Re@c}@iv8C@-0QyFT*JNSK^6{^;!)k>NC%!cnd z@2yE8xyJV?rw6#}dr}ju?Cc3oMXm{Fl1){{yAvlY-p%QzOE^6+k+EtspfGgKgP8+5 zSTNEo@yEV}euug13+cCwA%_U9cCPb<8K0;@5B{2iI{?JAc=e6*mqYGHuoNxONKnCA zLitAMe{cWSIYK?kL$ba$-=>C919_9jj*J`uHvH|+_Fh232~LBp_y5@#_k0wF=H!zn z{%9Auxf1->|K}wfl!+pd^gsWj{etwWoX^T*{|U1Hkrb?I{Us;h50Dcl5?s`aL!p^} zF8z#RI=FnwBjOK`&p#hl{fmV`7qZ(HWM2vu-RoAJ#Bif!){PDm2QALEqzAltMYuPG*-Bc}FTT2!8qpsERd7)WVw# zgZ9j#ICy=0_R(kSuY;pOd*ma zf?=j`jIAtf@l=!06fiQsQucRDT5*Ft>sGHcH%R2GOcN~+)($!8s8{$$uOkSks>|rO zZ3($B^^)C+S4TZ!+d=aO z-R(<^+^ofNnqLP^^YXmH$ef(aO#}%=fw!00b|~ zW1~e0^aP~`-M9;`OFYvhQodDn4#q})2e9|+D9%F9HtoKrCY*>kIX9E$OR$FNngY<0 z&>DAu6}6DseLd#8HMvLqnJNON4_TaRwE!g?-E;md7@0$^BuK;f6JKZ*wM4Nd?%1nq_ zs9=}F?#GNebDVbHK8eA+&uw@+LE2?l$Q8Y9#^GJgkud71g7ATUs+A}rZ1i>m?uox% zOm0pLLax%gUc(Lhg==HNVtH>9v`p|`<}_P`R&0y%l?1(8Dem!x()xUv#y)eLZqbN* zDydYmDqA+re<4c#HBTf;mM%_tiycWNXF@|-tsv)s%kv$}*rdnEpMy-t?Q&)a8>ilBaFIdPun}0d0->M+?_I_;j zxdRE4U0+b(Nk&`H&zcFFYyg_fECAm9P#_v|9LY<48 zA8;+TM6XvpJtRJhLAE9CKnyd_Q@@9t;}jPq&%tH8+2p0|oq{LE;lI;*&uO;K6fHGJ zWFO)B@0C)XkS75$O3#VcB_;lU3&TneVpH`D)v#I4>?lP0mQ@E5gDuuQ|!am-k!5;%NE_!zd< z4psH7oMh9@jJZJ1&uKf$+zPmUR38aH|mQ5s)$vHq#L*0)SQ&3h7;#bm^n z!xTL#7=<~KT!kE51!9s@MM>e>v{WJ#l)F)L`HFGF7iu7HUWkV+O{Tz_Q<@jw5t_2v z9O8;DZDFqFG_RRmPq@!X+TE^Bg(xPYd+=m3y3L?2-Tja3NAkb$Wt39 z(~t+xXQ2|qHyo@+u~RHi^-FSg2C;RGHC-P{uETy~JYN?&;!K|Zjc)0GjFx8RLyPGG z%s<==D13|tL{ggY3?ez+q?OWD*i~on)b`9Q><)IeM%mN`+O5XC_9Tye*qkiF;|?gs z477ZmQ^olKqPkg{rIC8}JnduhqwyE&QN?&~==#!q?+wZSCz=);dwd z&(ea|!p+w}(jhmSb>|g{u){}{wRM28C=)4S9ZGNfyuBtL(h#~ePaL32By}}TJ8n2)jmGc6rH?f|B$-u0Ke`bG zSz?@wo=BiK#4)gxr!B`mmJR=5{2R%0WGhg0Ib(J=l?Im_1~y9I5j$&L1o*9hhi}5Zh4gJf#aY4XRj6V*)p- zkUb$icL)2i==jF-EY#FD>}v3ViRh|#GRp^2w<7{?SplW+xpthK{xsW-+k3=@D(Vw0 zn`=qIQ%L-+rIr|TmsGx$fCX&+c*aA~YC+`LQ*0#;j<6u=BK6u-A+1nWfq^hu^ZP)%SoO9D3p+JED`E*=WFDd#LV#@Ad=^0 zE?w)+uC5jpp||-Xj>tCgeIN#{nc%~(_+N|eQ{S=``yJwbcErRv$qe zp~vX;ATt{x?deud@*>XszSXWkO#eS}n$PMDh|ZWie;o*=2?mm0o;tpWkUY(n`5klh z3yLfmu{&Z*)+&?c4a0P~F7nM{E`95NejWG^ZvOwHp#1<2U3Xk@D?kwCNSnZ)HjE5> M((?r6`1$Mq1hqi+O8@`> From d546db0990ab7ddc1d4cfb850c76fd60654e559b Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Fri, 9 Aug 2024 18:33:53 +0000 Subject: [PATCH 05/11] improve LaTeX docs --- examples/assets/panel-sympy.png | Bin 0 -> 6965 bytes examples/reference/panes/LaTeX.ipynb | 75 +++++++++++++++++++++------ panel/pane/equation.py | 6 +-- 3 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 examples/assets/panel-sympy.png diff --git a/examples/assets/panel-sympy.png b/examples/assets/panel-sympy.png new file mode 100644 index 0000000000000000000000000000000000000000..f1b666c82b2fc5162da1919344da12f68d7a1486 GIT binary patch literal 6965 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 literal 0 HcmV?d00001 diff --git a/examples/reference/panes/LaTeX.ipynb b/examples/reference/panes/LaTeX.ipynb index f6c236f2eb..0b13467e90 100644 --- a/examples/reference/panes/LaTeX.ipynb +++ b/examples/reference/panes/LaTeX.ipynb @@ -15,24 +15,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The ``LaTeX`` pane allows rendering LaTeX equations as HTML. It uses either [MathJax](https://www.mathjax.org) or [KaTeX](https://katex.org/) depending on the defined renderer. By default it will use the renderer loaded in the extension (e.g. ``pn.extension('katex')``), defaulting to KaTeX.\n", + "The `LaTeX` pane enables rendering LaTeX equations as HTML using either the [KaTeX](https://katex.org/) or [MathJax](https://www.mathjax.org) renderer.\n", + "\n", + "You must load the desired renderer manually (e.g., `pn.extension('katex')` or `pn.extension('mathjax')`). If both are loaded, KaTeX is used by default.\n", + "\n", + "Please note that both [KaTeX](https://katex.org/) and [MathJax](https://www.mathjax.org) support only a subset of the features available in a full LaTeX renderer. For detailed information on supported features, refer to their respective documentation.\n", "\n", "#### Parameters:\n", "\n", - "For details on other options for customizing the component see the [layout](../../how_to/layout/index.md) and [styling](../../how_to/styling/index.md) how-to guides.\n", + "For details on additional options for customizing the component, refer to the [layout](../../how_to/layout/index.md) and [styling](../../how_to/styling/index.md) how-to guides.\n", "\n", - "* **``object``** (str or object): A string containing LaTeX code, an object with a ``_repr_latex_`` method, or a SymPy expression\n", - "* **``renderer``** (object): The current value; must be one of the option values\n", - "* **``styles``** (dict): Dictionary specifying CSS styles\n", + "* **`object`** (str or object): A string containing LaTeX code, an object with a `_repr_latex_` method, or a [SymPy](https://www.sympy.org/en/index.html) expression.\n", + "* **`renderer`** (object): The current renderer; must be one of the available options.\n", + "* **`styles`** (dict): A dictionary specifying CSS styles.\n", "\n", - "___" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A ``LaTeX`` pane will render any object with a ``_repr_latex_`` method as well as SymPy expressions, or any string containing HTML. Any ``LaTeX`` section should be wrapped in `$` or ``\\(`` and ``\\(`` delimiters, e.g.:" + "___\n", + "\n", + "A `LaTeX` pane will render any object with a `_repr_latex_` method, [SymPy](https://www.sympy.org/en/index.html) expressions, or any string containing LaTeX. Any LaTeX content should be wrapped in `$...$` or `\\(...\\)` delimiters, for example:" ] }, { @@ -62,7 +61,7 @@ "outputs": [], "source": [ "pn.Column(\n", - " pn.pane.LaTeX(\"$\\frac{1}{n}$\"),\n", + " pn.pane.LaTeX(\"$\\frac{1}{n}$\"), # Will not work\n", " pn.pane.LaTeX(r\"$\\frac{1}{n}$\")\n", ")" ] @@ -83,6 +82,22 @@ "latex.object = r'$\\sum_{j}{\\sum_{i}{a*w_{j, i}}}$'" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Lets change it back:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "latex.object = r'The LaTeX pane supports two delimiters: $LaTeX$ and \\(LaTeX\\)'" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -96,7 +111,7 @@ "metadata": {}, "outputs": [], "source": [ - "pn.pane.LaTeX(r'$\\sum_{j}{\\sum_{i}{a*w_{j, i}}}$', renderer='mathjax', styles={'font-size': '18pt'})" + "pn.pane.LaTeX(r'The LaTeX pane supports two delimiters: $LaTeX$ and \\(LaTeX\\)', renderer='mathjax', styles={'font-size': '18pt'})" ] }, { @@ -158,6 +173,36 @@ "source": [ "pn.Row(latex.controls(jslink=True), latex)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sympy\n", + "\n", + "Panels LaTeX pane can render Sympy expressions as shown below:\n", + "\n", + "```python\n", + "import sympy as sp\n", + "import panel as pn\n", + "\n", + "pn.extension(\"mathjax\")\n", + "\n", + "# Define a symbol and a symbolic expression using SymPy\n", + "x = sp.symbols('x')\n", + "expression = sp.integrate(sp.sin(x)**2, x)\n", + "\n", + "# Create a LaTeX pane to display the expression\n", + "latex_pane = pn.pane.LaTeX(expression, styles={'font-size': '20px'})\n", + "\n", + "# Serve the panel\n", + "pn.Column(\n", + " \"# A sympy expression rendered in Panel: \", latex_pane\n", + ")\n", + "```\n", + "\n", + "![Sympy in LaTeX pane](../../assets/panel-sympy.png)" + ] } ], "metadata": { diff --git a/panel/pane/equation.py b/panel/pane/equation.py index afcd59f6e3..09a495087b 100644 --- a/panel/pane/equation.py +++ b/panel/pane/equation.py @@ -36,10 +36,10 @@ def is_sympy_expr(obj: Any) -> bool: class LaTeX(ModelPane): r""" The `LaTeX` pane allows rendering LaTeX equations. It uses either - `MathJax` or `KaTeX` depending on the defined renderer. + `KaTeX` or `MathJax` depending on the defined renderer. By default it will use the renderer loaded in the extension - (e.g. `pn.extension('katex')`), defaulting to `KaTeX`. + (e.g. `pn.extension('katex')`), defaulting to `KaTeX` if both are loaded. Reference: https://panel.holoviz.org/reference/panes/LaTeX.html @@ -54,7 +54,7 @@ class LaTeX(ModelPane): renderer = param.ObjectSelector(default=None, allow_None=True, objects=['katex', 'mathjax'], doc=""" - The JS renderer used to render the LaTeX expression.""") + The JS renderer used to render the LaTeX expression. Defaults to katex.""") # Priority is dependent on the data type priority: ClassVar[float | bool | None] = None From 340f05a6b6f83959c031898267f278fece26ff41 Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Fri, 9 Aug 2024 18:40:27 +0000 Subject: [PATCH 06/11] Optimize PNG images (lossless) --- examples/assets/panel-sympy.png | Bin 6965 -> 5608 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/assets/panel-sympy.png b/examples/assets/panel-sympy.png index f1b666c82b2fc5162da1919344da12f68d7a1486..5a869598f6e6bc8bcc2a265d4a56191aff9ae71f 100644 GIT binary patch literal 5608 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 literal 6965 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 From f21a2b97aa3fadad22cf0358eccbdfb04b4c83a8 Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Fri, 9 Aug 2024 19:41:23 +0000 Subject: [PATCH 07/11] vizz version --- examples/reference/panes/Vizzu.ipynb | 18 +++++++++++++++--- panel/models/vizzu.py | 3 ++- panel/tests/ui/pane/test_vizzu.py | 4 ++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/examples/reference/panes/Vizzu.ipynb b/examples/reference/panes/Vizzu.ipynb index 3d58a4be5b..17e4f57a4e 100644 --- a/examples/reference/panes/Vizzu.ipynb +++ b/examples/reference/panes/Vizzu.ipynb @@ -26,8 +26,8 @@ "For details on other options for customizing the component see the [layout](../../how_to/layout/index.md) and [styling](../../how_to/styling/index.md) how-to guides.\n", "\n", "* **``object``** (dict | pd.DataFrame): The data expressed as a Python dictionary of arrays or DataFrame.\n", - "* **``animation``** (dict): Animation settings (see [vizzu.Anim](https://lib.vizzuhq.com/latest/reference/modules/Anim/)).\n", - "* **``config``** (dict): The config contains all of the parameters needed to render a particular static chart or a state of an animated chart (see [vizzu.Config.Chart](https://lib.vizzuhq.com/latest/reference/interfaces/Config.Chart/)).\n", + "* **``animation``** (dict): Animation settings.\n", + "* **``config``** (dict): The config contains all of the parameters needed to render a particular static chart or a state of an animated chart.\n", "* **``columns``** (list): Optional column definitions. If not defined will be inferred from the data.\n", "* **``tooltips``** (boolean): Whether to enable tooltips on the chart.\n", "\n", @@ -36,7 +36,19 @@ "* **`animate`**: Accepts a dictionary of new 'data', 'config' and 'style' values which is used to update the chart.\n", "* **`stream`**: Streams new data to the plot.\n", "* **`patch`**: Patches one or more rows in the data.\n", - "___" + "___\n", + "\n", + "We currently support the version of Vizzu below:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from panel.models.vizzu import VERSION\n", + "VERSION" ] }, { diff --git a/panel/models/vizzu.py b/panel/models/vizzu.py index 7e42714d9f..ed8d19737a 100644 --- a/panel/models/vizzu.py +++ b/panel/models/vizzu.py @@ -11,6 +11,7 @@ from ..config import config from ..util import classproperty +VERSION = "0.9.3" class VizzuEvent(ModelEvent): @@ -30,7 +31,7 @@ class VizzuChart(LayoutDOM): __javascript_module_exports__ = ['Vizzu'] __javascript_modules__ = [ - f"{config.npm_cdn}/vizzu@0.9.3/dist/vizzu.min.js" + f"{config.npm_cdn}/vizzu@{VERSION}/dist/vizzu.min.js" ] @classproperty diff --git a/panel/tests/ui/pane/test_vizzu.py b/panel/tests/ui/pane/test_vizzu.py index d9da764e94..3558a5dad6 100644 --- a/panel/tests/ui/pane/test_vizzu.py +++ b/panel/tests/ui/pane/test_vizzu.py @@ -6,6 +6,7 @@ from playwright.sync_api import expect +from panel.models.vizzu import VERSION from panel.pane import Vizzu from panel.tests.util import serve_component, wait_until @@ -54,3 +55,6 @@ def test_vizzu_click(page): wait_until(lambda: len(clicks) == 1, page) assert clicks[0]['categories'] == {'Name': 'Patrick'} + +def test_can_import_version(): + assert VERSION From d1ab9b14530aa7377e480ab310391fe73910a195 Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Sat, 31 Aug 2024 12:00:04 +0000 Subject: [PATCH 08/11] Sphinx update vizzu version --- doc/conf.py | 12 +++++++----- examples/reference/panes/Vizzu.ipynb | 12 +----------- panel/models/vizzu.py | 4 ++-- panel/tests/ui/pane/test_vizzu.py | 4 ++-- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index cbdfa33cb7..2f918633e0 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -243,14 +243,16 @@ def _get_pyodide_version(): def update_versions(app, docname, source): from panel.models.tabulator import TABULATOR_VERSION + from panel.models.vizzu import VIZZU_VERSION # Inspired by: https://stackoverflow.com/questions/8821511 version_replace = { - "{{PANEL_VERSION}}" : PY_VERSION, - "{{BOKEH_VERSION}}" : BOKEH_VERSION, - "{{PYSCRIPT_VERSION}}" : PYSCRIPT_VERSION, - "{{PYODIDE_VERSION}}" : _get_pyodide_version(), - "{{TABULATOR_VERSION}}" : TABULATOR_VERSION, + "{{PANEL_VERSION}}" : PY_VERSION, + "{{BOKEH_VERSION}}" : BOKEH_VERSION, + "{{PYSCRIPT_VERSION}}" : PYSCRIPT_VERSION, + "{{PYODIDE_VERSION}}" : _get_pyodide_version(), + "{{TABULATOR_VERSION}}" : TABULATOR_VERSION, + "{{VIZZU_VERSION}}" : VIZZU_VERSION, } for old, new in version_replace.items(): diff --git a/examples/reference/panes/Vizzu.ipynb b/examples/reference/panes/Vizzu.ipynb index 17e4f57a4e..204963d863 100644 --- a/examples/reference/panes/Vizzu.ipynb +++ b/examples/reference/panes/Vizzu.ipynb @@ -38,17 +38,7 @@ "* **`patch`**: Patches one or more rows in the data.\n", "___\n", "\n", - "We currently support the version of Vizzu below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from panel.models.vizzu import VERSION\n", - "VERSION" + "The `Vizzu` pane is built on **version {{VIZZU_VERSION}}** of the [Vizzu Javascript](https://lib.vizzuhq.com/latest/) library." ] }, { diff --git a/panel/models/vizzu.py b/panel/models/vizzu.py index ed8d19737a..4a682fba9c 100644 --- a/panel/models/vizzu.py +++ b/panel/models/vizzu.py @@ -11,7 +11,7 @@ from ..config import config from ..util import classproperty -VERSION = "0.9.3" +VIZZU_VERSION = "0.9.3" class VizzuEvent(ModelEvent): @@ -31,7 +31,7 @@ class VizzuChart(LayoutDOM): __javascript_module_exports__ = ['Vizzu'] __javascript_modules__ = [ - f"{config.npm_cdn}/vizzu@{VERSION}/dist/vizzu.min.js" + f"{config.npm_cdn}/vizzu@{VIZZU_VERSION}/dist/vizzu.min.js" ] @classproperty diff --git a/panel/tests/ui/pane/test_vizzu.py b/panel/tests/ui/pane/test_vizzu.py index 3558a5dad6..4a8fb1f0bd 100644 --- a/panel/tests/ui/pane/test_vizzu.py +++ b/panel/tests/ui/pane/test_vizzu.py @@ -6,7 +6,7 @@ from playwright.sync_api import expect -from panel.models.vizzu import VERSION +from panel.models.vizzu import VIZZU_VERSION from panel.pane import Vizzu from panel.tests.util import serve_component, wait_until @@ -57,4 +57,4 @@ def test_vizzu_click(page): assert clicks[0]['categories'] == {'Name': 'Patrick'} def test_can_import_version(): - assert VERSION + assert VIZZU_VERSION From 240dea0953eccecb724e0691c3e3ad0e0499fe5a Mon Sep 17 00:00:00 2001 From: Philipp Rudiger Date: Wed, 11 Sep 2024 19:06:31 +0200 Subject: [PATCH 09/11] Apply suggestions from code review --- doc/explanation/api/examples/outliers_declarative.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/explanation/api/examples/outliers_declarative.md b/doc/explanation/api/examples/outliers_declarative.md index e68d51fed6..8418b2cbac 100644 --- a/doc/explanation/api/examples/outliers_declarative.md +++ b/doc/explanation/api/examples/outliers_declarative.md @@ -101,7 +101,7 @@ Save the notebook with the name `app.ipynb`. Finally, we'll serve the app by running the command below in a terminal: ```bash -panel serve app.ipynb --autoreload +panel serve app.ipynb --dev ``` Now, open the app in your browser at [http://localhost:5006/app](http://localhost:5006/app). From faa9ce6c95b31bd5f49cd051881e99225fa2724b Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Sun, 15 Sep 2024 03:53:15 +0000 Subject: [PATCH 10/11] make it easy to copy code --- doc/getting_started/build_app.md | 62 ++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/doc/getting_started/build_app.md b/doc/getting_started/build_app.md index b99363816e..7911e572fc 100644 --- a/doc/getting_started/build_app.md +++ b/doc/getting_started/build_app.md @@ -135,15 +135,71 @@ It should look like this: ![Getting Started App](../_static/images/getting_started_app.png) -:::{tip} +::::{tip} -If you prefer developing in a Python Script using an editor, you can copy the code into a file `app.py` and serve it. +If you prefer developing in a Python Script using an editor, you can copy the *code* into a file `app.py` and serve it. + +:::{dropdown} code + +```python +import hvplot.pandas +import numpy as np +import pandas as pd +import panel as pn + +PRIMARY_COLOR = "#0072B5" +SECONDARY_COLOR = "#B54300" +CSV_FILE = ( + "https://raw.githubusercontent.com/holoviz/panel/main/examples/assets/occupancy.csv" +) + +pn.extension(design="material", sizing_mode="stretch_width") + +@pn.cache +def get_data(): + return pd.read_csv(CSV_FILE, parse_dates=["date"], index_col="date") + +data = get_data() + +def transform_data(variable, window, sigma): + """Calculates the rolling average and identifies outliers""" + avg = data[variable].rolling(window=window).mean() + residual = data[variable] - avg + std = residual.rolling(window=window).std() + outliers = np.abs(residual) > std * sigma + return avg, avg[outliers] + + +def get_plot(variable="Temperature", window=30, sigma=10): + """Plots the rolling average and the outliers""" + avg, highlight = transform_data(variable, window, sigma) + return avg.hvplot( + height=300, legend=False, color=PRIMARY_COLOR + ) * highlight.hvplot.scatter(color=SECONDARY_COLOR, padding=0.1, legend=False) + +variable_widget = pn.widgets.Select(name="variable", value="Temperature", options=list(data.columns)) +window_widget = pn.widgets.IntSlider(name="window", value=30, start=1, end=60) +sigma_widget = pn.widgets.IntSlider(name="sigma", value=10, start=0, end=20) + +bound_plot = pn.bind( + get_plot, variable=variable_widget, window=window_widget, sigma=sigma_widget +) + +pn.template.MaterialTemplate( + site="Panel", + title="Getting Started App", + sidebar=[variable_widget, window_widget, sigma_widget], + main=[bound_plot], +).servable(); # The ; is needed in the notebook to not display the template. Its not needed in a script +``` + +::: ```bash panel serve app.py --dev ``` -::: +:::: ## What's Next? From b2505b075dc0e45d3b0472df4175e8b6b353b48a Mon Sep 17 00:00:00 2001 From: MarcSkovMadsen Date: Sun, 15 Sep 2024 04:32:54 +0000 Subject: [PATCH 11/11] review feedback - remove update section --- doc/getting_started/installation.md | 32 ----------------------------- 1 file changed, 32 deletions(-) diff --git a/doc/getting_started/installation.md b/doc/getting_started/installation.md index 247fd16c89..8a0cee4118 100644 --- a/doc/getting_started/installation.md +++ b/doc/getting_started/installation.md @@ -78,38 +78,6 @@ Make sure Panel is installed in the same environment as JupyterLab/Jupyter Noteb If you plan to use Panel in a non-Jupyter notebook environment, such as Google Colab or VSCode, refer to the [relevant how-to section](../how_to/notebook/other_nb.md). ::: -## Updating Panel - -:::{important} - -Instead of updating, we recommend that you create a new virtual environment from scratch and reinstall Panel to minimize the risk of potential issues. - -::: - -We suggest updating the dependencies `param` and `bokeh` along with `panel` and `watchfiles` to reduce the likelihood of problems. - -:::::{tab-set} - -::::{tab-item} pip -:sync: pip - -```bash -pip install --upgrade panel watchfiles param bokeh -``` - -:::: - -::::{tab-item} conda -:sync: conda - -```bash -conda update panel watchfiles param bokeh -``` - -:::: - -::::: - ## Next Steps Now that you have installed Panel, let's [build a simple application](build_app.md).