vizforge 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vizforge/__init__.py +48 -0
- vizforge/charts/__init__.py +18 -0
- vizforge/charts/bar.py +260 -0
- vizforge/charts/line.py +217 -0
- vizforge/charts/pie.py +217 -0
- vizforge/charts/scatter.py +321 -0
- vizforge/core/__init__.py +13 -0
- vizforge/core/base.py +266 -0
- vizforge/core/theme.py +261 -0
- vizforge/examples/basic_examples.py +260 -0
- vizforge-0.1.0.dist-info/METADATA +292 -0
- vizforge-0.1.0.dist-info/RECORD +15 -0
- vizforge-0.1.0.dist-info/WHEEL +5 -0
- vizforge-0.1.0.dist-info/licenses/LICENSE +21 -0
- vizforge-0.1.0.dist-info/top_level.txt +1 -0
vizforge/__init__.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
VizForge - Production-grade data visualization library with zero AI dependencies.
|
|
3
|
+
|
|
4
|
+
Create beautiful, interactive visualizations with a single line of code.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .core import (
|
|
8
|
+
BaseChart,
|
|
9
|
+
Theme,
|
|
10
|
+
get_theme,
|
|
11
|
+
set_theme,
|
|
12
|
+
register_theme,
|
|
13
|
+
list_themes,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from .charts import (
|
|
17
|
+
LineChart,
|
|
18
|
+
line,
|
|
19
|
+
BarChart,
|
|
20
|
+
bar,
|
|
21
|
+
ScatterPlot,
|
|
22
|
+
scatter,
|
|
23
|
+
PieChart,
|
|
24
|
+
pie,
|
|
25
|
+
donut,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
__version__ = "0.1.0"
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
# Core
|
|
32
|
+
"BaseChart",
|
|
33
|
+
"Theme",
|
|
34
|
+
"get_theme",
|
|
35
|
+
"set_theme",
|
|
36
|
+
"register_theme",
|
|
37
|
+
"list_themes",
|
|
38
|
+
# Charts
|
|
39
|
+
"LineChart",
|
|
40
|
+
"line",
|
|
41
|
+
"BarChart",
|
|
42
|
+
"bar",
|
|
43
|
+
"ScatterPlot",
|
|
44
|
+
"scatter",
|
|
45
|
+
"PieChart",
|
|
46
|
+
"pie",
|
|
47
|
+
"donut",
|
|
48
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""VizForge chart types."""
|
|
2
|
+
|
|
3
|
+
from .line import LineChart, line
|
|
4
|
+
from .bar import BarChart, bar
|
|
5
|
+
from .scatter import ScatterPlot, scatter
|
|
6
|
+
from .pie import PieChart, pie, donut
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"LineChart",
|
|
10
|
+
"line",
|
|
11
|
+
"BarChart",
|
|
12
|
+
"bar",
|
|
13
|
+
"ScatterPlot",
|
|
14
|
+
"scatter",
|
|
15
|
+
"PieChart",
|
|
16
|
+
"pie",
|
|
17
|
+
"donut",
|
|
18
|
+
]
|
vizforge/charts/bar.py
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"""Bar chart implementation for VizForge."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional, Union
|
|
4
|
+
import plotly.graph_objects as go
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from ..core.base import BaseChart
|
|
9
|
+
from ..core.theme import Theme
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BarChart(BaseChart):
|
|
13
|
+
"""
|
|
14
|
+
Bar chart visualization.
|
|
15
|
+
|
|
16
|
+
Supports vertical and horizontal bars, grouped and stacked layouts.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
data: Optional[Union[pd.DataFrame, dict, list]] = None,
|
|
22
|
+
x: Optional[Union[str, list, np.ndarray]] = None,
|
|
23
|
+
y: Optional[Union[str, list, np.ndarray]] = None,
|
|
24
|
+
title: Optional[str] = None,
|
|
25
|
+
theme: Optional[Union[str, Theme]] = None,
|
|
26
|
+
orientation: str = "v",
|
|
27
|
+
barmode: str = "group",
|
|
28
|
+
color: Optional[Union[str, list]] = None,
|
|
29
|
+
**kwargs
|
|
30
|
+
):
|
|
31
|
+
"""
|
|
32
|
+
Create a bar chart.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
data: Data source (DataFrame, dict, or list)
|
|
36
|
+
x: X-axis data or column name
|
|
37
|
+
y: Y-axis data or column name
|
|
38
|
+
title: Chart title
|
|
39
|
+
theme: Theme name or Theme object
|
|
40
|
+
orientation: 'v' for vertical, 'h' for horizontal
|
|
41
|
+
barmode: 'group', 'stack', 'relative', or 'overlay'
|
|
42
|
+
color: Column name for color grouping or list of colors
|
|
43
|
+
**kwargs: Additional arguments
|
|
44
|
+
|
|
45
|
+
Example:
|
|
46
|
+
>>> bar = BarChart(data=df, x='category', y='value', title='Sales by Category')
|
|
47
|
+
>>> bar.show()
|
|
48
|
+
"""
|
|
49
|
+
super().__init__(title=title, theme=theme, **kwargs)
|
|
50
|
+
self.orientation = orientation
|
|
51
|
+
self.barmode = barmode
|
|
52
|
+
self.color = color
|
|
53
|
+
|
|
54
|
+
if data is not None:
|
|
55
|
+
self.plot(data, x, y)
|
|
56
|
+
|
|
57
|
+
def plot(
|
|
58
|
+
self,
|
|
59
|
+
data: Union[pd.DataFrame, dict, list],
|
|
60
|
+
x: Optional[Union[str, list, np.ndarray]] = None,
|
|
61
|
+
y: Optional[Union[str, list, np.ndarray]] = None,
|
|
62
|
+
name: Optional[str] = None,
|
|
63
|
+
**kwargs
|
|
64
|
+
) -> 'BarChart':
|
|
65
|
+
"""
|
|
66
|
+
Plot data on the chart.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
data: Data source
|
|
70
|
+
x: X-axis data or column name
|
|
71
|
+
y: Y-axis data or column name
|
|
72
|
+
name: Series name
|
|
73
|
+
**kwargs: Additional trace arguments
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Self for method chaining
|
|
77
|
+
"""
|
|
78
|
+
# Create figure if not exists
|
|
79
|
+
if self.fig is None:
|
|
80
|
+
self.fig = self._create_figure()
|
|
81
|
+
self.fig.update_layout(barmode=self.barmode)
|
|
82
|
+
|
|
83
|
+
# Parse data
|
|
84
|
+
if self.color and isinstance(data, pd.DataFrame) and isinstance(self.color, str):
|
|
85
|
+
# Grouped bars by color column
|
|
86
|
+
self._plot_grouped(data, x, y, self.color, **kwargs)
|
|
87
|
+
else:
|
|
88
|
+
# Simple bar chart
|
|
89
|
+
x_data, y_data_list, names = self._parse_data(data, x, y, name)
|
|
90
|
+
|
|
91
|
+
for y_data, trace_name in zip(y_data_list, names):
|
|
92
|
+
if self.orientation == "v":
|
|
93
|
+
self.fig.add_trace(
|
|
94
|
+
go.Bar(
|
|
95
|
+
x=x_data,
|
|
96
|
+
y=y_data,
|
|
97
|
+
name=trace_name,
|
|
98
|
+
**kwargs
|
|
99
|
+
)
|
|
100
|
+
)
|
|
101
|
+
else:
|
|
102
|
+
self.fig.add_trace(
|
|
103
|
+
go.Bar(
|
|
104
|
+
x=y_data,
|
|
105
|
+
y=x_data,
|
|
106
|
+
name=trace_name,
|
|
107
|
+
orientation='h',
|
|
108
|
+
**kwargs
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return self
|
|
113
|
+
|
|
114
|
+
def _plot_grouped(
|
|
115
|
+
self,
|
|
116
|
+
data: pd.DataFrame,
|
|
117
|
+
x: str,
|
|
118
|
+
y: str,
|
|
119
|
+
color: str,
|
|
120
|
+
**kwargs
|
|
121
|
+
) -> None:
|
|
122
|
+
"""Plot grouped bars by color column."""
|
|
123
|
+
groups = data[color].unique()
|
|
124
|
+
|
|
125
|
+
for group in groups:
|
|
126
|
+
group_data = data[data[color] == group]
|
|
127
|
+
|
|
128
|
+
if self.orientation == "v":
|
|
129
|
+
self.fig.add_trace(
|
|
130
|
+
go.Bar(
|
|
131
|
+
x=group_data[x],
|
|
132
|
+
y=group_data[y],
|
|
133
|
+
name=str(group),
|
|
134
|
+
**kwargs
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
else:
|
|
138
|
+
self.fig.add_trace(
|
|
139
|
+
go.Bar(
|
|
140
|
+
x=group_data[y],
|
|
141
|
+
y=group_data[x],
|
|
142
|
+
name=str(group),
|
|
143
|
+
orientation='h',
|
|
144
|
+
**kwargs
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def _parse_data(
|
|
149
|
+
self,
|
|
150
|
+
data: Union[pd.DataFrame, dict, list],
|
|
151
|
+
x: Optional[Union[str, list, np.ndarray]],
|
|
152
|
+
y: Optional[Union[str, list, np.ndarray]],
|
|
153
|
+
name: Optional[str]
|
|
154
|
+
) -> tuple[Any, list[Any], list[str]]:
|
|
155
|
+
"""Parse different data formats into x, y, and names."""
|
|
156
|
+
|
|
157
|
+
# Handle DataFrame
|
|
158
|
+
if isinstance(data, pd.DataFrame):
|
|
159
|
+
if isinstance(x, str):
|
|
160
|
+
x_data = data[x].values
|
|
161
|
+
elif x is None:
|
|
162
|
+
x_data = data.index.values
|
|
163
|
+
else:
|
|
164
|
+
x_data = x
|
|
165
|
+
|
|
166
|
+
if isinstance(y, str):
|
|
167
|
+
y_data_list = [data[y].values]
|
|
168
|
+
names = [name or y]
|
|
169
|
+
elif isinstance(y, list) and all(isinstance(col, str) for col in y):
|
|
170
|
+
# Multiple y columns
|
|
171
|
+
y_data_list = [data[col].values for col in y]
|
|
172
|
+
names = y if name is None else [f"{name} - {col}" for col in y]
|
|
173
|
+
else:
|
|
174
|
+
y_data_list = [y]
|
|
175
|
+
names = [name or "trace"]
|
|
176
|
+
|
|
177
|
+
return x_data, y_data_list, names
|
|
178
|
+
|
|
179
|
+
# Handle dict
|
|
180
|
+
elif isinstance(data, dict):
|
|
181
|
+
if isinstance(x, str):
|
|
182
|
+
x_data = data[x]
|
|
183
|
+
else:
|
|
184
|
+
x_data = x
|
|
185
|
+
|
|
186
|
+
if isinstance(y, str):
|
|
187
|
+
y_data_list = [data[y]]
|
|
188
|
+
names = [name or y]
|
|
189
|
+
elif isinstance(y, list) and all(isinstance(col, str) for col in y):
|
|
190
|
+
y_data_list = [data[col] for col in y]
|
|
191
|
+
names = y if name is None else [f"{name} - {col}" for col in y]
|
|
192
|
+
else:
|
|
193
|
+
y_data_list = [y]
|
|
194
|
+
names = [name or "trace"]
|
|
195
|
+
|
|
196
|
+
return x_data, y_data_list, names
|
|
197
|
+
|
|
198
|
+
# Handle arrays/lists
|
|
199
|
+
else:
|
|
200
|
+
x_data = x
|
|
201
|
+
y_data_list = [y]
|
|
202
|
+
names = [name or "trace"]
|
|
203
|
+
return x_data, y_data_list, names
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def bar(
|
|
207
|
+
data: Union[pd.DataFrame, dict, list],
|
|
208
|
+
x: Optional[Union[str, list, np.ndarray]] = None,
|
|
209
|
+
y: Optional[Union[str, list, np.ndarray]] = None,
|
|
210
|
+
title: Optional[str] = None,
|
|
211
|
+
theme: Optional[Union[str, Theme]] = None,
|
|
212
|
+
orientation: str = "v",
|
|
213
|
+
barmode: str = "group",
|
|
214
|
+
color: Optional[Union[str, list]] = None,
|
|
215
|
+
show: bool = True,
|
|
216
|
+
export: Optional[str] = None,
|
|
217
|
+
**kwargs
|
|
218
|
+
) -> BarChart:
|
|
219
|
+
"""
|
|
220
|
+
Create and display a bar chart (convenience function).
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
data: Data source (DataFrame, dict, or list)
|
|
224
|
+
x: X-axis data or column name
|
|
225
|
+
y: Y-axis data or column name
|
|
226
|
+
title: Chart title
|
|
227
|
+
theme: Theme name or Theme object
|
|
228
|
+
orientation: 'v' for vertical, 'h' for horizontal
|
|
229
|
+
barmode: 'group', 'stack', 'relative', or 'overlay'
|
|
230
|
+
color: Column name for color grouping
|
|
231
|
+
show: Whether to display the chart
|
|
232
|
+
export: Export filename (optional)
|
|
233
|
+
**kwargs: Additional arguments
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
BarChart object
|
|
237
|
+
|
|
238
|
+
Example:
|
|
239
|
+
>>> bar(df, x='category', y='value', title='Sales by Category')
|
|
240
|
+
>>> bar(df, x='month', y='revenue', color='region', barmode='stack')
|
|
241
|
+
"""
|
|
242
|
+
chart = BarChart(
|
|
243
|
+
data=data,
|
|
244
|
+
x=x,
|
|
245
|
+
y=y,
|
|
246
|
+
title=title,
|
|
247
|
+
theme=theme,
|
|
248
|
+
orientation=orientation,
|
|
249
|
+
barmode=barmode,
|
|
250
|
+
color=color,
|
|
251
|
+
**kwargs
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
if export:
|
|
255
|
+
chart.export(export)
|
|
256
|
+
|
|
257
|
+
if show:
|
|
258
|
+
chart.show()
|
|
259
|
+
|
|
260
|
+
return chart
|
vizforge/charts/line.py
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""Line chart implementation for VizForge."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional, Union
|
|
4
|
+
import plotly.graph_objects as go
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from ..core.base import BaseChart
|
|
9
|
+
from ..core.theme import Theme
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class LineChart(BaseChart):
|
|
13
|
+
"""
|
|
14
|
+
Line chart visualization.
|
|
15
|
+
|
|
16
|
+
Supports single and multi-line charts, area charts, and step charts.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
data: Optional[Union[pd.DataFrame, dict, list]] = None,
|
|
22
|
+
x: Optional[Union[str, list, np.ndarray]] = None,
|
|
23
|
+
y: Optional[Union[str, list, np.ndarray]] = None,
|
|
24
|
+
title: Optional[str] = None,
|
|
25
|
+
theme: Optional[Union[str, Theme]] = None,
|
|
26
|
+
mode: str = "lines",
|
|
27
|
+
fill: Optional[str] = None,
|
|
28
|
+
**kwargs
|
|
29
|
+
):
|
|
30
|
+
"""
|
|
31
|
+
Create a line chart.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
data: Data source (DataFrame, dict, or list)
|
|
35
|
+
x: X-axis data or column name
|
|
36
|
+
y: Y-axis data or column name (can be list of columns for multi-line)
|
|
37
|
+
title: Chart title
|
|
38
|
+
theme: Theme name or Theme object
|
|
39
|
+
mode: Display mode ('lines', 'markers', 'lines+markers')
|
|
40
|
+
fill: Fill area ('none', 'tozeroy', 'tonexty')
|
|
41
|
+
**kwargs: Additional arguments
|
|
42
|
+
|
|
43
|
+
Example:
|
|
44
|
+
>>> line = LineChart(data=df, x='date', y='sales', title='Sales Trend')
|
|
45
|
+
>>> line.show()
|
|
46
|
+
"""
|
|
47
|
+
super().__init__(title=title, theme=theme, **kwargs)
|
|
48
|
+
self.mode = mode
|
|
49
|
+
self.fill = fill
|
|
50
|
+
|
|
51
|
+
if data is not None:
|
|
52
|
+
self.plot(data, x, y)
|
|
53
|
+
|
|
54
|
+
def plot(
|
|
55
|
+
self,
|
|
56
|
+
data: Union[pd.DataFrame, dict, list],
|
|
57
|
+
x: Optional[Union[str, list, np.ndarray]] = None,
|
|
58
|
+
y: Optional[Union[str, list, np.ndarray]] = None,
|
|
59
|
+
name: Optional[str] = None,
|
|
60
|
+
**kwargs
|
|
61
|
+
) -> 'LineChart':
|
|
62
|
+
"""
|
|
63
|
+
Plot data on the chart.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
data: Data source
|
|
67
|
+
x: X-axis data or column name
|
|
68
|
+
y: Y-axis data or column name
|
|
69
|
+
name: Series name
|
|
70
|
+
**kwargs: Additional trace arguments
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Self for method chaining
|
|
74
|
+
"""
|
|
75
|
+
# Create figure if not exists
|
|
76
|
+
if self.fig is None:
|
|
77
|
+
self.fig = self._create_figure()
|
|
78
|
+
|
|
79
|
+
# Parse data
|
|
80
|
+
x_data, y_data_list, names = self._parse_data(data, x, y, name)
|
|
81
|
+
|
|
82
|
+
# Add traces
|
|
83
|
+
for y_data, trace_name in zip(y_data_list, names):
|
|
84
|
+
trace_kwargs = {
|
|
85
|
+
'mode': self.mode,
|
|
86
|
+
'line': {'width': self._theme.line_width},
|
|
87
|
+
'marker': {'size': self._theme.marker_size},
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if self.fill:
|
|
91
|
+
trace_kwargs['fill'] = self.fill
|
|
92
|
+
|
|
93
|
+
trace_kwargs.update(kwargs)
|
|
94
|
+
|
|
95
|
+
self.fig.add_trace(
|
|
96
|
+
go.Scatter(
|
|
97
|
+
x=x_data,
|
|
98
|
+
y=y_data,
|
|
99
|
+
name=trace_name,
|
|
100
|
+
**trace_kwargs
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
return self
|
|
105
|
+
|
|
106
|
+
def _parse_data(
|
|
107
|
+
self,
|
|
108
|
+
data: Union[pd.DataFrame, dict, list],
|
|
109
|
+
x: Optional[Union[str, list, np.ndarray]],
|
|
110
|
+
y: Optional[Union[str, list, np.ndarray]],
|
|
111
|
+
name: Optional[str]
|
|
112
|
+
) -> tuple[Any, list[Any], list[str]]:
|
|
113
|
+
"""Parse different data formats into x, y, and names."""
|
|
114
|
+
|
|
115
|
+
# Handle DataFrame
|
|
116
|
+
if isinstance(data, pd.DataFrame):
|
|
117
|
+
if isinstance(x, str):
|
|
118
|
+
x_data = data[x].values
|
|
119
|
+
elif x is None:
|
|
120
|
+
x_data = data.index.values
|
|
121
|
+
else:
|
|
122
|
+
x_data = x
|
|
123
|
+
|
|
124
|
+
if isinstance(y, str):
|
|
125
|
+
y_data_list = [data[y].values]
|
|
126
|
+
names = [name or y]
|
|
127
|
+
elif isinstance(y, list) and all(isinstance(col, str) for col in y):
|
|
128
|
+
# Multiple y columns
|
|
129
|
+
y_data_list = [data[col].values for col in y]
|
|
130
|
+
names = y if name is None else [f"{name} - {col}" for col in y]
|
|
131
|
+
else:
|
|
132
|
+
y_data_list = [y]
|
|
133
|
+
names = [name or "trace"]
|
|
134
|
+
|
|
135
|
+
return x_data, y_data_list, names
|
|
136
|
+
|
|
137
|
+
# Handle dict
|
|
138
|
+
elif isinstance(data, dict):
|
|
139
|
+
if x is None:
|
|
140
|
+
x_data = list(range(len(next(iter(data.values())))))
|
|
141
|
+
elif isinstance(x, str):
|
|
142
|
+
x_data = data[x]
|
|
143
|
+
else:
|
|
144
|
+
x_data = x
|
|
145
|
+
|
|
146
|
+
if isinstance(y, str):
|
|
147
|
+
y_data_list = [data[y]]
|
|
148
|
+
names = [name or y]
|
|
149
|
+
elif isinstance(y, list) and all(isinstance(col, str) for col in y):
|
|
150
|
+
y_data_list = [data[col] for col in y]
|
|
151
|
+
names = y if name is None else [f"{name} - {col}" for col in y]
|
|
152
|
+
else:
|
|
153
|
+
y_data_list = [y]
|
|
154
|
+
names = [name or "trace"]
|
|
155
|
+
|
|
156
|
+
return x_data, y_data_list, names
|
|
157
|
+
|
|
158
|
+
# Handle arrays/lists
|
|
159
|
+
else:
|
|
160
|
+
x_data = x if x is not None else list(range(len(y)))
|
|
161
|
+
y_data_list = [y]
|
|
162
|
+
names = [name or "trace"]
|
|
163
|
+
return x_data, y_data_list, names
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def line(
|
|
167
|
+
data: Union[pd.DataFrame, dict, list],
|
|
168
|
+
x: Optional[Union[str, list, np.ndarray]] = None,
|
|
169
|
+
y: Optional[Union[str, list, np.ndarray]] = None,
|
|
170
|
+
title: Optional[str] = None,
|
|
171
|
+
theme: Optional[Union[str, Theme]] = None,
|
|
172
|
+
mode: str = "lines",
|
|
173
|
+
fill: Optional[str] = None,
|
|
174
|
+
show: bool = True,
|
|
175
|
+
export: Optional[str] = None,
|
|
176
|
+
**kwargs
|
|
177
|
+
) -> LineChart:
|
|
178
|
+
"""
|
|
179
|
+
Create and display a line chart (convenience function).
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
data: Data source (DataFrame, dict, or list)
|
|
183
|
+
x: X-axis data or column name
|
|
184
|
+
y: Y-axis data or column name
|
|
185
|
+
title: Chart title
|
|
186
|
+
theme: Theme name or Theme object
|
|
187
|
+
mode: Display mode ('lines', 'markers', 'lines+markers')
|
|
188
|
+
fill: Fill area ('none', 'tozeroy', 'tonexty')
|
|
189
|
+
show: Whether to display the chart
|
|
190
|
+
export: Export filename (optional)
|
|
191
|
+
**kwargs: Additional arguments
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
LineChart object
|
|
195
|
+
|
|
196
|
+
Example:
|
|
197
|
+
>>> line(df, x='date', y='sales', title='Sales Trend')
|
|
198
|
+
>>> line(df, x='date', y=['sales', 'profit'], theme='dark')
|
|
199
|
+
"""
|
|
200
|
+
chart = LineChart(
|
|
201
|
+
data=data,
|
|
202
|
+
x=x,
|
|
203
|
+
y=y,
|
|
204
|
+
title=title,
|
|
205
|
+
theme=theme,
|
|
206
|
+
mode=mode,
|
|
207
|
+
fill=fill,
|
|
208
|
+
**kwargs
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
if export:
|
|
212
|
+
chart.export(export)
|
|
213
|
+
|
|
214
|
+
if show:
|
|
215
|
+
chart.show()
|
|
216
|
+
|
|
217
|
+
return chart
|