forked from scikit-hep/uproot-browser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plot_view.py
112 lines (93 loc) · 3.43 KB
/
plot_view.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from __future__ import annotations
from typing import Any
import plotext as plt
import rich.align
import rich.ansi
import rich.box
import rich.console
import rich.panel
import rich.pretty
import rich.text
import textual.view
import textual.widget
import uproot
import uproot_browser.dirs
import uproot_browser.plot
EMPTY = object()
def make_plot(item: Any, *size: int) -> Any:
plt.clf()
plt.plotsize(*size)
plt.title("Plotext Integration in Rich - Test")
uproot_browser.plot.plot(item)
return plt.build()
class Plot:
def __init__(self, item: Any) -> None:
self.decoder = rich.ansi.AnsiDecoder()
self.item: Any = item
def __rich_console__(
self, console: rich.console.Console, options: rich.console.ConsoleOptions
) -> rich.console.RenderResult:
width = options.max_width or console.width
height = options.height or console.height
try:
canvas = make_plot(self.item, width, height)
rich_canvas = rich.console.Group(*self.decoder.decode(canvas))
except Exception:
rich_canvas = rich.console.Group(
rich.traceback.Traceback(
extra_lines=1,
max_frames=4, # Can't be less than 4 frames
)
)
if options.height is not None:
options.height -= 4
yield from rich_canvas.__rich_console__(console, options)
return
yield rich_canvas
class PlotWidget(textual.widget.Widget): # type: ignore[misc]
height: textual.widget.Reactive[int | None] = textual.widget.Reactive(None)
def __init__(self, uproot_file: uproot.ReadOnlyFile) -> None:
super().__init__()
self.file = uproot_file
self.plot = EMPTY
def set_plot(self, plot_path: str | None) -> None:
if plot_path is None:
self.plot = plot_path
else:
*_, item = uproot_browser.dirs.apply_selection(
self.file, plot_path.split(":")
)
self.plot = Plot(item)
async def update(self) -> None:
self.refresh()
def render(self) -> rich.console.RenderableType:
if self.plot is None:
return rich.panel.Panel(
rich.align.Align.center(
rich.pretty.Pretty(
"No plot selected!", no_wrap=True, overflow="ellipsis"
),
vertical="middle",
),
border_style="red",
box=rich.box.ROUNDED,
height=self.height,
)
if self.plot is EMPTY:
return rich.panel.Panel(
rich.align.Align.center(
rich.text.Text.from_ansi(
"""
┬ ┬┌─┐┬─┐┌─┐┌─┐┌┬┐4 ┌┐ ┬─┐┌─┐┬ ┬┌─┐┌─┐┬─┐
│ │├─┘├┬┘│ ││ │ │───├┴┐├┬┘│ ││││└─┐├┤ ├┬┘
└─┘┴ ┴└─└─┘└─┘ ┴ └─┘┴└─└─┘└┴┘└─┘└─┘┴└─
powered by Hist""",
no_wrap=True,
),
vertical="middle",
),
border_style="green",
box=rich.box.ROUNDED,
height=self.height,
)
return rich.panel.Panel(self.plot) # type: ignore[arg-type]