plotext-plus 1.0.9__py3-none-any.whl → 1.0.10__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.
plotext_plus/_api.py CHANGED
@@ -1,5 +1,4 @@
1
1
  # /usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
 
4
3
  """
5
4
  Modern Plotext API - A cleaner, more intuitive interface for creating terminal charts
@@ -8,21 +7,25 @@ backward compatibility with the existing plotext API.
8
7
  """
9
8
 
10
9
  import plotext_plus._core as _core
11
- from plotext_plus._output import set_output_mode, info, success, warning, error
10
+ from plotext_plus._output import error
11
+ from plotext_plus._output import info
12
+ from plotext_plus._output import set_output_mode
13
+ from plotext_plus._output import success
14
+ from plotext_plus._output import warning
12
15
 
13
16
 
14
17
  class Chart:
15
18
  """
16
19
  Modern object-oriented interface for creating charts.
17
-
20
+
18
21
  This class provides a chainable API for building charts with method chaining
19
22
  and cleaner separation of concerns.
20
23
  """
21
-
24
+
22
25
  def __init__(self, use_banners=False, banner_title=None):
23
26
  """
24
27
  Initialize a new chart.
25
-
28
+
26
29
  Args:
27
30
  use_banners (bool): Whether to display charts in chuk-term banners
28
31
  banner_title (str): Title for the banner (if enabled)
@@ -32,205 +35,310 @@ class Chart:
32
35
  self._data = []
33
36
  self._legend = None
34
37
  self._config = {
35
- 'title': None,
36
- 'x_label': None,
37
- 'y_label': None,
38
- 'width': None,
39
- 'height': None,
40
- 'theme': 'default'
38
+ "title": None,
39
+ "x_label": None,
40
+ "y_label": None,
41
+ "width": None,
42
+ "height": None,
43
+ "theme": "default",
41
44
  }
42
-
45
+
43
46
  # Configure output mode
44
47
  if use_banners:
45
48
  set_output_mode(True, banner_title)
46
49
  # When using banners, automatically set appropriate size to fit within banner
47
50
  from plotext_plus import _utility as _ut
48
- banner_width = _ut.terminal_width() # This now returns adjusted width for banners
51
+
52
+ banner_width = (
53
+ _ut.terminal_width()
54
+ ) # This now returns adjusted width for banners
49
55
  if banner_width:
50
- self._config['width'] = banner_width
51
-
56
+ self._config["width"] = banner_width
57
+
52
58
  def scatter(self, x, y, marker=None, color=None, label=None):
53
59
  """Add scatter plot data"""
54
- self._data.append({
55
- 'type': 'scatter',
56
- 'x': x,
57
- 'y': y,
58
- 'marker': marker,
59
- 'color': color,
60
- 'label': label
61
- })
62
- return self
63
-
60
+ self._data.append(
61
+ {
62
+ "type": "scatter",
63
+ "x": x,
64
+ "y": y,
65
+ "marker": marker,
66
+ "color": color,
67
+ "label": label,
68
+ }
69
+ )
70
+ return self
71
+
64
72
  def line(self, x, y, marker=None, color=None, label=None):
65
73
  """Add line plot data"""
66
- self._data.append({
67
- 'type': 'line',
68
- 'x': x,
69
- 'y': y,
70
- 'marker': marker,
71
- 'color': color,
72
- 'label': label
73
- })
74
- return self
75
-
74
+ self._data.append(
75
+ {
76
+ "type": "line",
77
+ "x": x,
78
+ "y": y,
79
+ "marker": marker,
80
+ "color": color,
81
+ "label": label,
82
+ }
83
+ )
84
+ return self
85
+
76
86
  def bar(self, labels, values, color=None, horizontal=False):
77
87
  """Add bar chart data"""
78
- self._data.append({
79
- 'type': 'bar',
80
- 'labels': labels,
81
- 'values': values,
82
- 'color': color,
83
- 'horizontal': horizontal
84
- })
85
- return self
86
-
87
- def pie(self, labels, values, colors=None, radius=None, show_values=True, show_percentages=True, show_values_on_slices=False, donut=False, remaining_color=None):
88
+ self._data.append(
89
+ {
90
+ "type": "bar",
91
+ "labels": labels,
92
+ "values": values,
93
+ "color": color,
94
+ "horizontal": horizontal,
95
+ }
96
+ )
97
+ return self
98
+
99
+ def pie(
100
+ self,
101
+ labels,
102
+ values,
103
+ colors=None,
104
+ radius=None,
105
+ show_values=True,
106
+ show_percentages=True,
107
+ show_values_on_slices=False,
108
+ donut=False,
109
+ remaining_color=None,
110
+ ):
88
111
  """Add pie chart data"""
89
- self._data.append({
90
- 'type': 'pie',
91
- 'labels': labels,
92
- 'values': values,
93
- 'colors': colors,
94
- 'radius': radius,
95
- 'show_values': show_values,
96
- 'show_percentages': show_percentages,
97
- 'show_values_on_slices': show_values_on_slices,
98
- 'donut': donut,
99
- 'remaining_color': remaining_color
100
- })
101
- return self
102
-
112
+ self._data.append(
113
+ {
114
+ "type": "pie",
115
+ "labels": labels,
116
+ "values": values,
117
+ "colors": colors,
118
+ "radius": radius,
119
+ "show_values": show_values,
120
+ "show_percentages": show_percentages,
121
+ "show_values_on_slices": show_values_on_slices,
122
+ "donut": donut,
123
+ "remaining_color": remaining_color,
124
+ }
125
+ )
126
+ return self
127
+
103
128
  def title(self, title):
104
129
  """Set chart title"""
105
- self._config['title'] = title
130
+ self._config["title"] = title
106
131
  return self
107
-
132
+
108
133
  def xlabel(self, label):
109
134
  """Set x-axis label"""
110
- self._config['x_label'] = label
135
+ self._config["x_label"] = label
111
136
  return self
112
-
137
+
113
138
  def ylabel(self, label):
114
139
  """Set y-axis label"""
115
- self._config['y_label'] = label
140
+ self._config["y_label"] = label
116
141
  return self
117
-
142
+
118
143
  def size(self, width=None, height=None):
119
144
  """Set chart size"""
120
- self._config['width'] = width
121
- self._config['height'] = height
145
+ self._config["width"] = width
146
+ self._config["height"] = height
122
147
  return self
123
-
148
+
124
149
  def theme(self, theme_name):
125
150
  """Set chart theme"""
126
- self._config['theme'] = theme_name
151
+ self._config["theme"] = theme_name
127
152
  return self
128
-
153
+
129
154
  def banner_title(self, title):
130
155
  """Set banner title (if banner mode is enabled)"""
131
156
  self.banner_title = title
132
157
  if self.use_banners:
133
158
  set_output_mode(True, title)
134
159
  return self
135
-
160
+
136
161
  def legend(self, legend_instance=None):
137
162
  """
138
163
  Set or get legend for this chart
139
-
164
+
140
165
  Args:
141
166
  legend_instance (Legend): Legend instance to apply to chart
142
-
167
+
143
168
  Returns:
144
169
  Chart: Self for chaining, or current legend if no args provided
145
170
  """
146
171
  if legend_instance is None:
147
172
  return self._legend
148
-
173
+
149
174
  self._legend = legend_instance
150
175
  legend_instance.apply_to_chart(self)
151
176
  return self
152
-
177
+
153
178
  def show(self):
154
179
  """Render and display the chart"""
155
180
  # Clear any existing plot data
156
181
  _core.clear_figure()
157
-
182
+
183
+ # Apply theme if specified
184
+ if self._config["theme"] and self._config["theme"] != "default":
185
+ _core.theme(self._config["theme"])
186
+
158
187
  # Configure plot settings
159
- if self._config['title']:
160
- _core.title(self._config['title'])
161
- if self._config['x_label']:
162
- _core.xlabel(self._config['x_label'])
163
- if self._config['y_label']:
164
- _core.ylabel(self._config['y_label'])
165
- if self._config['width'] or self._config['height']:
166
- _core.plot_size(self._config['width'], self._config['height'])
167
-
188
+ if self._config["title"]:
189
+ _core.title(self._config["title"])
190
+ if self._config["x_label"]:
191
+ _core.xlabel(self._config["x_label"])
192
+ if self._config["y_label"]:
193
+ _core.ylabel(self._config["y_label"])
194
+ if self._config["width"] or self._config["height"]:
195
+ _core.plot_size(self._config["width"], self._config["height"])
196
+
168
197
  # Add data to plot
169
198
  for data_item in self._data:
170
- if data_item['type'] == 'scatter':
199
+ if data_item["type"] == "scatter":
171
200
  _core.scatter(
172
- data_item['x'],
173
- data_item['y'],
174
- marker=data_item['marker'],
175
- color=data_item['color'],
176
- label=data_item['label']
201
+ data_item["x"],
202
+ data_item["y"],
203
+ marker=data_item["marker"],
204
+ color=data_item["color"],
205
+ label=data_item["label"],
177
206
  )
178
- elif data_item['type'] == 'line':
207
+ elif data_item["type"] == "line":
179
208
  _core.plot(
180
- data_item['x'],
181
- data_item['y'],
182
- marker=data_item['marker'],
183
- color=data_item['color'],
184
- label=data_item['label']
209
+ data_item["x"],
210
+ data_item["y"],
211
+ marker=data_item["marker"],
212
+ color=data_item["color"],
213
+ label=data_item["label"],
185
214
  )
186
- elif data_item['type'] == 'bar':
187
- if data_item['horizontal']:
188
- _core.horizontal_bar(data_item['labels'], data_item['values'], color=data_item['color'])
189
- else:
190
- _core.bar(data_item['labels'], data_item['values'], color=data_item['color'])
191
- elif data_item['type'] == 'pie':
215
+ elif data_item["type"] == "bar":
216
+ orientation = "horizontal" if data_item["horizontal"] else "vertical"
217
+ _core.bar(
218
+ data_item["labels"],
219
+ data_item["values"],
220
+ color=data_item["color"],
221
+ orientation=orientation,
222
+ )
223
+ elif data_item["type"] == "pie":
192
224
  _core.pie(
193
- data_item['labels'],
194
- data_item['values'],
195
- colors=data_item['colors'],
196
- radius=data_item['radius'],
197
- show_values=data_item['show_values'],
198
- show_percentages=data_item['show_percentages'],
199
- show_values_on_slices=data_item['show_values_on_slices'],
200
- donut=data_item.get('donut', False),
201
- remaining_color=data_item.get('remaining_color', None)
225
+ data_item["labels"],
226
+ data_item["values"],
227
+ colors=data_item["colors"],
228
+ radius=data_item["radius"],
229
+ show_values=data_item["show_values"],
230
+ show_percentages=data_item["show_percentages"],
231
+ show_values_on_slices=data_item["show_values_on_slices"],
232
+ donut=data_item.get("donut", False),
233
+ remaining_color=data_item.get("remaining_color", None),
234
+ )
235
+ elif data_item["type"] == "histogram":
236
+ _core.hist(
237
+ data_item["data"], bins=data_item["bins"], color=data_item["color"]
202
238
  )
203
- elif data_item['type'] == 'histogram':
204
- _core.hist(data_item['data'], bins=data_item['bins'], color=data_item['color'])
205
-
239
+
206
240
  # Display the chart
207
241
  _core.show()
208
242
  return self
209
-
210
- def save(self, path, format='txt'):
243
+
244
+ def save(self, path, format="txt"):
211
245
  """Save chart to file"""
212
- if format == 'html':
246
+ if format == "html":
213
247
  _core.save_fig(path, keep_colors=True)
214
248
  else:
215
249
  _core.save_fig(path)
216
250
  return self
217
251
 
252
+ def __str__(self):
253
+ """Return the chart as a string without displaying it"""
254
+ # Clear any existing plot data
255
+ _core.clear_figure()
256
+
257
+ # Apply theme if specified
258
+ if self._config["theme"] and self._config["theme"] != "default":
259
+ _core.theme(self._config["theme"])
260
+
261
+ # Configure plot settings
262
+ if self._config["title"]:
263
+ _core.title(self._config["title"])
264
+ if self._config["x_label"]:
265
+ _core.xlabel(self._config["x_label"])
266
+ if self._config["y_label"]:
267
+ _core.ylabel(self._config["y_label"])
268
+ if self._config["width"] or self._config["height"]:
269
+ _core.plot_size(self._config["width"], self._config["height"])
270
+
271
+ # Add data to plot
272
+ for data_item in self._data:
273
+ if data_item["type"] == "scatter":
274
+ _core.scatter(
275
+ data_item["x"],
276
+ data_item["y"],
277
+ marker=data_item["marker"],
278
+ color=data_item["color"],
279
+ label=data_item["label"],
280
+ )
281
+ elif data_item["type"] == "line":
282
+ _core.plot(
283
+ data_item["x"],
284
+ data_item["y"],
285
+ marker=data_item["marker"],
286
+ color=data_item["color"],
287
+ label=data_item["label"],
288
+ )
289
+ elif data_item["type"] == "bar":
290
+ orientation = "horizontal" if data_item["horizontal"] else "vertical"
291
+ _core.bar(
292
+ data_item["labels"],
293
+ data_item["values"],
294
+ color=data_item["color"],
295
+ orientation=orientation,
296
+ )
297
+ elif data_item["type"] == "pie":
298
+ _core.pie(
299
+ data_item["labels"],
300
+ data_item["values"],
301
+ colors=data_item["colors"],
302
+ radius=data_item["radius"],
303
+ show_values=data_item["show_values"],
304
+ show_percentages=data_item["show_percentages"],
305
+ show_values_on_slices=data_item["show_values_on_slices"],
306
+ donut=data_item.get("donut", False),
307
+ remaining_color=data_item.get("remaining_color", None),
308
+ )
309
+ elif data_item["type"] == "histogram":
310
+ _core.hist(
311
+ data_item["data"], bins=data_item["bins"], color=data_item["color"]
312
+ )
313
+
314
+ # Build and return the chart as a string instead of displaying
315
+ return _core.build()
316
+
218
317
 
219
318
  class ScatterChart(Chart):
220
319
  """
221
320
  Specialized class for creating scatter plots with a focused API
222
321
  """
223
-
224
- def __init__(self, x, y, marker=None, color=None, label=None, use_banners=False, banner_title=None):
322
+
323
+ def __init__(
324
+ self,
325
+ x,
326
+ y,
327
+ marker=None,
328
+ color=None,
329
+ label=None,
330
+ use_banners=False,
331
+ banner_title=None,
332
+ ):
225
333
  """Initialize a scatter chart with data"""
226
334
  super().__init__(use_banners, banner_title)
227
335
  self.scatter(x, y, marker, color, label)
228
-
229
- def add_trend_line(self, x, y, color='red', label='Trend'):
336
+
337
+ def add_trend_line(self, x, y, color="red", label="Trend"):
230
338
  """Add a trend line to the scatter plot"""
231
339
  self.line(x, y, color=color, label=label)
232
340
  return self
233
-
341
+
234
342
  def add_regression(self):
235
343
  """Add linear regression line (future enhancement)"""
236
344
  # Placeholder for regression functionality
@@ -241,17 +349,26 @@ class LineChart(Chart):
241
349
  """
242
350
  Specialized class for creating line charts with enhanced features
243
351
  """
244
-
245
- def __init__(self, x, y, marker=None, color=None, label=None, use_banners=False, banner_title=None):
352
+
353
+ def __init__(
354
+ self,
355
+ x,
356
+ y,
357
+ marker=None,
358
+ color=None,
359
+ label=None,
360
+ use_banners=False,
361
+ banner_title=None,
362
+ ):
246
363
  """Initialize a line chart with data"""
247
364
  super().__init__(use_banners, banner_title)
248
365
  self.line(x, y, marker, color, label)
249
-
366
+
250
367
  def add_fill(self, fillx=False, filly=False):
251
368
  """Add fill under the line (future enhancement)"""
252
369
  # Placeholder for fill functionality
253
370
  return self
254
-
371
+
255
372
  def smooth(self, window_size=3):
256
373
  """Apply smoothing to the line (future enhancement)"""
257
374
  # Placeholder for smoothing functionality
@@ -262,29 +379,39 @@ class BarChart(Chart):
262
379
  """
263
380
  Specialized class for creating bar charts with extensive customization
264
381
  """
265
-
266
- def __init__(self, labels, values, color=None, horizontal=False, use_banners=False, banner_title=None):
382
+
383
+ def __init__(
384
+ self,
385
+ labels,
386
+ values,
387
+ color=None,
388
+ horizontal=False,
389
+ use_banners=False,
390
+ banner_title=None,
391
+ ):
267
392
  """Initialize a bar chart with data"""
268
393
  super().__init__(use_banners, banner_title)
269
394
  self.bar(labels, values, color, horizontal)
270
395
  self.labels = labels
271
396
  self.values = values
272
-
397
+
273
398
  def stack(self, values, color=None, label=None):
274
399
  """Add stacked bars (future enhancement)"""
275
400
  # Placeholder for stacked bar functionality
276
401
  return self
277
-
402
+
278
403
  def group(self, values, color=None, label=None):
279
404
  """Add grouped bars (future enhancement)"""
280
405
  # Placeholder for grouped bar functionality
281
406
  return self
282
-
407
+
283
408
  def sort_by_value(self, ascending=True):
284
409
  """Sort bars by value"""
285
410
  # Simple implementation for sorting
286
- sorted_pairs = sorted(zip(self.values, self.labels), reverse=not ascending)
287
- self.values, self.labels = zip(*sorted_pairs)
411
+ sorted_pairs = sorted(
412
+ zip(self.values, self.labels, strict=False), reverse=not ascending
413
+ )
414
+ self.values, self.labels = zip(*sorted_pairs, strict=False)
288
415
  return self
289
416
 
290
417
 
@@ -292,30 +419,27 @@ class HistogramChart(Chart):
292
419
  """
293
420
  Specialized class for creating histograms with statistical features
294
421
  """
295
-
422
+
296
423
  def __init__(self, data, bins=20, color=None, use_banners=False, banner_title=None):
297
424
  """Initialize a histogram with data"""
298
425
  super().__init__(use_banners, banner_title)
299
426
  self.data = data
300
427
  self.bins = bins
301
428
  self._create_histogram(data, bins, color)
302
-
429
+
303
430
  def _create_histogram(self, data, bins, color):
304
431
  """Create histogram from raw data"""
305
432
  # Add histogram data to the chart
306
- self._data.append({
307
- 'type': 'histogram',
308
- 'data': data,
309
- 'bins': bins,
310
- 'color': color
311
- })
312
- return self
313
-
433
+ self._data.append(
434
+ {"type": "histogram", "data": data, "bins": bins, "color": color}
435
+ )
436
+ return self
437
+
314
438
  def add_normal_curve(self):
315
439
  """Overlay a normal distribution curve (future enhancement)"""
316
440
  # Placeholder for normal curve overlay
317
441
  return self
318
-
442
+
319
443
  def add_statistics(self):
320
444
  """Add mean, median, std dev lines (future enhancement)"""
321
445
  # Placeholder for statistical lines
@@ -326,11 +450,11 @@ class CandlestickChart(Chart):
326
450
  """
327
451
  Specialized class for financial candlestick charts
328
452
  """
329
-
453
+
330
454
  def __init__(self, dates, data, colors=None, use_banners=False, banner_title=None):
331
455
  """
332
456
  Initialize a candlestick chart
333
-
457
+
334
458
  Args:
335
459
  dates: List of dates
336
460
  data: List of [open, high, low, close] values
@@ -339,56 +463,49 @@ class CandlestickChart(Chart):
339
463
  super().__init__(use_banners, banner_title)
340
464
  self.dates = dates
341
465
  self.data = data
342
- self._data.append({
343
- 'type': 'candlestick',
344
- 'dates': dates,
345
- 'data': data,
346
- 'colors': colors
347
- })
348
-
349
- def add_volume(self, volumes, color='blue'):
466
+ self._data.append(
467
+ {"type": "candlestick", "dates": dates, "data": data, "colors": colors}
468
+ )
469
+
470
+ def add_volume(self, volumes, color="blue"):
350
471
  """Add volume bars below candlesticks (future enhancement)"""
351
472
  # Placeholder for volume functionality
352
473
  return self
353
-
354
- def add_moving_average(self, period=20, color='orange'):
474
+
475
+ def add_moving_average(self, period=20, color="orange"):
355
476
  """Add moving average line (future enhancement)"""
356
477
  # Placeholder for moving average
357
478
  return self
358
-
479
+
359
480
  def show(self):
360
481
  """Render and display the candlestick chart"""
361
482
  _core.clear_figure()
362
-
363
- if self._config['title']:
364
- _core.title(self._config['title'])
365
- if self._config['x_label']:
366
- _core.xlabel(self._config['x_label'])
367
- if self._config['y_label']:
368
- _core.ylabel(self._config['y_label'])
369
- if self._config['width'] or self._config['height']:
370
- _core.plot_size(self._config['width'], self._config['height'])
371
-
483
+
484
+ if self._config["title"]:
485
+ _core.title(self._config["title"])
486
+ if self._config["x_label"]:
487
+ _core.xlabel(self._config["x_label"])
488
+ if self._config["y_label"]:
489
+ _core.ylabel(self._config["y_label"])
490
+ if self._config["width"] or self._config["height"]:
491
+ _core.plot_size(self._config["width"], self._config["height"])
492
+
372
493
  for data_item in self._data:
373
- if data_item['type'] == 'candlestick':
494
+ if data_item["type"] == "candlestick":
374
495
  # Convert list format to dictionary format expected by plotext
375
- dates = data_item['dates']
376
- ohlc_data = data_item['data']
377
-
496
+ dates = data_item["dates"]
497
+ ohlc_data = data_item["data"]
498
+
378
499
  # Format data as expected by plotext candlestick function
379
500
  formatted_data = {
380
- 'Open': [item[0] for item in ohlc_data],
381
- 'High': [item[1] for item in ohlc_data],
382
- 'Low': [item[2] for item in ohlc_data],
383
- 'Close': [item[3] for item in ohlc_data]
501
+ "Open": [item[0] for item in ohlc_data],
502
+ "High": [item[1] for item in ohlc_data],
503
+ "Low": [item[2] for item in ohlc_data],
504
+ "Close": [item[3] for item in ohlc_data],
384
505
  }
385
-
386
- _core.candlestick(
387
- dates,
388
- formatted_data,
389
- colors=data_item['colors']
390
- )
391
-
506
+
507
+ _core.candlestick(dates, formatted_data, colors=data_item["colors"])
508
+
392
509
  _core.show()
393
510
  return self
394
511
 
@@ -397,11 +514,11 @@ class HeatmapChart(Chart):
397
514
  """
398
515
  Specialized class for creating heatmaps and matrix visualizations
399
516
  """
400
-
517
+
401
518
  def __init__(self, data, colorscale=None, use_banners=False, banner_title=None):
402
519
  """
403
520
  Initialize a heatmap chart
404
-
521
+
405
522
  Args:
406
523
  data: 2D matrix or pandas DataFrame
407
524
  colorscale: Color scale for the heatmap
@@ -409,209 +526,238 @@ class HeatmapChart(Chart):
409
526
  super().__init__(use_banners, banner_title)
410
527
  self.data = data
411
528
  self.colorscale = colorscale
412
- self._data.append({
413
- 'type': 'heatmap',
414
- 'data': data,
415
- 'colorscale': colorscale
416
- })
417
-
529
+ self._data.append({"type": "heatmap", "data": data, "colorscale": colorscale})
530
+
418
531
  def annotate(self, show_values=True):
419
532
  """Add value annotations to cells (future enhancement)"""
420
533
  # Placeholder for annotations
421
534
  return self
422
-
535
+
423
536
  def show(self):
424
537
  """Render and display the heatmap"""
425
538
  _core.clear_figure()
426
-
539
+
427
540
  # Set appropriate plot size for heatmaps FIRST - ensure full width usage
428
- if self._config['width'] or self._config['height']:
429
- _core.plotsize(self._config['width'], self._config['height'])
541
+ if self._config["width"] or self._config["height"]:
542
+ _core.plotsize(self._config["width"], self._config["height"])
430
543
  else:
431
544
  # Default to full terminal width for better heatmap display
432
545
  import plotext_plus._utility as _ut
546
+
433
547
  terminal_width = _ut.terminal_width()
434
548
  if terminal_width:
435
549
  # Set reasonable dimensions for heatmap display
436
550
  heatmap_height = max(20, len(self.data) * 6 + 10)
437
551
  _core.plotsize(terminal_width - 4, heatmap_height)
438
-
552
+
439
553
  # Configure plot settings (same as base Chart class)
440
- if self._config['title']:
441
- _core.title(self._config['title'])
442
- if self._config['x_label']:
443
- _core.xlabel(self._config['x_label'])
444
- if self._config['y_label']:
445
- _core.ylabel(self._config['y_label'])
446
-
554
+ if self._config["title"]:
555
+ _core.title(self._config["title"])
556
+ if self._config["x_label"]:
557
+ _core.xlabel(self._config["x_label"])
558
+ if self._config["y_label"]:
559
+ _core.ylabel(self._config["y_label"])
560
+
447
561
  for data_item in self._data:
448
- if data_item['type'] == 'heatmap':
449
- data = data_item['data']
450
-
562
+ if data_item["type"] == "heatmap":
563
+ data = data_item["data"]
564
+
451
565
  # Check if data is a pandas DataFrame
452
- if hasattr(data, 'columns'):
566
+ if hasattr(data, "columns"):
453
567
  # It's already a DataFrame
454
- _core.heatmap(data, color=data_item['colorscale'])
568
+ _core.heatmap(data, color=data_item["colorscale"])
455
569
  else:
456
570
  # It's a list/matrix, create filled heatmap blocks
457
- self._draw_filled_heatmap(data, data_item['colorscale'])
458
-
571
+ self._draw_filled_heatmap(data, data_item["colorscale"])
572
+
459
573
  _core.show()
460
574
  return self
461
-
575
+
462
576
  def _draw_list_heatmap(self, matrix, colorscale):
463
577
  """Draw a heatmap using continuous colored blocks"""
464
578
  if not matrix or not matrix[0]:
465
579
  return
466
-
580
+
467
581
  rows = len(matrix)
468
582
  cols = len(matrix[0])
469
-
583
+
470
584
  # Flatten and normalize the data for color mapping
471
585
  flat_data = [val for row in matrix for val in row]
472
586
  min_val = min(flat_data)
473
587
  max_val = max(flat_data)
474
588
  value_range = max_val - min_val if max_val != min_val else 1
475
-
589
+
476
590
  # Define color palette
477
591
  color_palettes = {
478
- 'plasma': ['black', 'purple', 'magenta', 'red', 'orange', 'yellow'],
479
- 'viridis': ['black', 'blue', 'green', 'bright green', 'yellow'],
480
- 'cool': ['cyan', 'blue', 'magenta', 'white'],
481
- 'hot': ['black', 'red', 'orange', 'yellow', 'white'],
482
- 'default': ['blue', 'cyan', 'green', 'yellow', 'red', 'magenta']
592
+ "plasma": ["black", "purple", "magenta", "red", "orange", "yellow"],
593
+ "viridis": ["black", "blue", "green", "bright green", "yellow"],
594
+ "cool": ["cyan", "blue", "magenta", "white"],
595
+ "hot": ["black", "red", "orange", "yellow", "white"],
596
+ "default": ["blue", "cyan", "green", "yellow", "red", "magenta"],
483
597
  }
484
- colors = color_palettes.get(colorscale, color_palettes['default'])
485
-
598
+ colors = color_palettes.get(colorscale, color_palettes["default"])
599
+
486
600
  # Create heatmap using continuous filled rectangles for each cell
487
601
  for row_idx in range(rows):
488
602
  row_data = matrix[row_idx]
489
603
  y_level = rows - row_idx - 1 # Flip so row 0 is at top
490
-
604
+
491
605
  for col_idx, value in enumerate(row_data):
492
606
  # Normalize value to get color
493
607
  normalized = (value - min_val) / value_range
494
608
  color_idx = int(normalized * (len(colors) - 1))
495
609
  color = colors[min(color_idx, len(colors) - 1)]
496
-
610
+
497
611
  # Create a continuous filled rectangle for this cell
498
612
  # Use multiple closely spaced points to fill the area
499
613
  cell_points_x = []
500
614
  cell_points_y = []
501
-
615
+
502
616
  # Fill the cell with dense points to create solid appearance
503
- for x_offset in [-0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45]:
504
- for y_offset in [-0.45, -0.35, -0.25, -0.15, -0.05, 0.05, 0.15, 0.25, 0.35, 0.45]:
617
+ for x_offset in [
618
+ -0.45,
619
+ -0.35,
620
+ -0.25,
621
+ -0.15,
622
+ -0.05,
623
+ 0.05,
624
+ 0.15,
625
+ 0.25,
626
+ 0.35,
627
+ 0.45,
628
+ ]:
629
+ for y_offset in [
630
+ -0.45,
631
+ -0.35,
632
+ -0.25,
633
+ -0.15,
634
+ -0.05,
635
+ 0.05,
636
+ 0.15,
637
+ 0.25,
638
+ 0.35,
639
+ 0.45,
640
+ ]:
505
641
  cell_points_x.append(col_idx + x_offset)
506
642
  cell_points_y.append(y_level + y_offset)
507
-
643
+
508
644
  # Draw all points for this cell at once with the same color
509
645
  if cell_points_x and cell_points_y:
510
- _core.scatter(cell_points_x, cell_points_y, color=color, marker='')
511
-
646
+ _core.scatter(cell_points_x, cell_points_y, color=color, marker="")
647
+
512
648
  # Set axis limits and labels to show the grid properly
513
649
  _core.xlim(-0.5, cols - 0.5)
514
650
  _core.ylim(-0.5, rows - 0.5)
515
- _core.xlabel('Column')
516
- _core.ylabel('Row')
517
-
651
+ _core.xlabel("Column")
652
+ _core.ylabel("Row")
653
+
518
654
  def _draw_filled_heatmap(self, matrix, colorscale):
519
655
  """Draw a heatmap using filled rectangular blocks for each cell"""
520
656
  if not matrix or not matrix[0]:
521
657
  return
522
-
658
+
523
659
  rows = len(matrix)
524
660
  cols = len(matrix[0])
525
-
661
+
526
662
  # Flatten and normalize the data for color mapping
527
663
  flat_data = [val for row in matrix for val in row]
528
664
  min_val = min(flat_data)
529
665
  max_val = max(flat_data)
530
666
  value_range = max_val - min_val if max_val != min_val else 1
531
-
667
+
532
668
  # Define color palette
533
669
  color_palettes = {
534
- 'plasma': ['black', 'purple', 'magenta', 'red', 'orange', 'yellow'],
535
- 'viridis': ['black', 'blue', 'green', 'bright green', 'yellow'],
536
- 'cool': ['cyan', 'blue', 'magenta', 'white'],
537
- 'hot': ['black', 'red', 'orange', 'yellow', 'white'],
538
- 'default': ['blue', 'cyan', 'green', 'yellow', 'red', 'magenta']
670
+ "plasma": ["black", "purple", "magenta", "red", "orange", "yellow"],
671
+ "viridis": ["black", "blue", "green", "bright green", "yellow"],
672
+ "cool": ["cyan", "blue", "magenta", "white"],
673
+ "hot": ["black", "red", "orange", "yellow", "white"],
674
+ "default": ["blue", "cyan", "green", "yellow", "red", "magenta"],
539
675
  }
540
- colors = color_palettes.get(colorscale, color_palettes['default'])
541
-
676
+ colors = color_palettes.get(colorscale, color_palettes["default"])
677
+
542
678
  # Create filled rectangles for each cell using bar charts
543
679
  for row_idx in range(rows):
544
680
  row_data = matrix[row_idx]
545
681
  y_center = rows - row_idx - 1 # Flip so row 0 is at top
546
-
682
+
547
683
  for col_idx, value in enumerate(row_data):
548
684
  # Normalize value to get color
549
685
  normalized = (value - min_val) / value_range
550
686
  color_idx = int(normalized * (len(colors) - 1))
551
687
  color = colors[min(color_idx, len(colors) - 1)]
552
-
688
+
553
689
  # Create a filled rectangle using horizontal bar at this cell position
554
690
  # Bar from col_idx-0.4 to col_idx+0.4, at y_center with height 0.8
555
691
  x_positions = []
556
692
  y_positions = []
557
-
693
+
558
694
  # Fill the rectangle with a dense grid of points
559
695
  x_steps = 20 # More density for smoother appearance
560
696
  y_steps = 8
561
-
697
+
562
698
  for i in range(x_steps + 1):
563
699
  for j in range(y_steps + 1):
564
700
  x_offset = (i / x_steps - 0.5) * 0.9 # -0.45 to +0.45
565
701
  y_offset = (j / y_steps - 0.5) * 0.9 # -0.45 to +0.45
566
702
  x_positions.append(col_idx + x_offset)
567
703
  y_positions.append(y_center + y_offset)
568
-
704
+
569
705
  # Draw all points for this cell with the same color
570
706
  if x_positions and y_positions:
571
- _core.scatter(x_positions, y_positions, color=color, marker='')
572
-
707
+ _core.scatter(x_positions, y_positions, color=color, marker="")
708
+
573
709
  # Set axis limits and labels to show the grid properly
574
710
  _core.xlim(-0.5, cols - 0.5)
575
711
  _core.ylim(-0.5, rows - 0.5)
576
- _core.xlabel('Column')
577
- _core.ylabel('Row')
712
+ _core.xlabel("Column")
713
+ _core.ylabel("Row")
578
714
 
579
715
 
580
716
  class MatrixChart(Chart):
581
717
  """
582
718
  Specialized class for matrix plotting with advanced features
583
719
  """
584
-
585
- def __init__(self, matrix, marker=None, style=None, fast=False, use_banners=False, banner_title=None):
720
+
721
+ def __init__(
722
+ self,
723
+ matrix,
724
+ marker=None,
725
+ style=None,
726
+ fast=False,
727
+ use_banners=False,
728
+ banner_title=None,
729
+ ):
586
730
  """Initialize a matrix plot"""
587
731
  super().__init__(use_banners, banner_title)
588
732
  self.matrix = matrix
589
- self._data.append({
590
- 'type': 'matrix',
591
- 'matrix': matrix,
592
- 'marker': marker,
593
- 'style': style,
594
- 'fast': fast
595
- })
596
-
733
+ self._data.append(
734
+ {
735
+ "type": "matrix",
736
+ "matrix": matrix,
737
+ "marker": marker,
738
+ "style": style,
739
+ "fast": fast,
740
+ }
741
+ )
742
+
597
743
  def show(self):
598
744
  """Render and display the matrix plot"""
599
745
  _core.clear_figure()
600
-
601
- if self._config['title']:
602
- _core.title(self._config['title'])
603
- if self._config['width'] or self._config['height']:
604
- _core.plot_size(self._config['width'], self._config['height'])
605
-
746
+
747
+ if self._config["title"]:
748
+ _core.title(self._config["title"])
749
+ if self._config["width"] or self._config["height"]:
750
+ _core.plot_size(self._config["width"], self._config["height"])
751
+
606
752
  for data_item in self._data:
607
- if data_item['type'] == 'matrix':
753
+ if data_item["type"] == "matrix":
608
754
  _core.matrix_plot(
609
- data_item['matrix'],
610
- marker=data_item['marker'],
611
- style=data_item['style'],
612
- fast=data_item['fast']
755
+ data_item["matrix"],
756
+ marker=data_item["marker"],
757
+ style=data_item["style"],
758
+ fast=data_item["fast"],
613
759
  )
614
-
760
+
615
761
  _core.show()
616
762
  return self
617
763
 
@@ -620,43 +766,47 @@ class StemChart(Chart):
620
766
  """
621
767
  Specialized class for stem plots (lollipop charts)
622
768
  """
623
-
624
- def __init__(self, x, y, color=None, orientation='vertical', use_banners=False, banner_title=None):
769
+
770
+ def __init__(
771
+ self,
772
+ x,
773
+ y,
774
+ color=None,
775
+ orientation="vertical",
776
+ use_banners=False,
777
+ banner_title=None,
778
+ ):
625
779
  """Initialize a stem chart"""
626
780
  super().__init__(use_banners, banner_title)
627
781
  self.x = x
628
782
  self.y = y
629
783
  self.orientation = orientation
630
784
  # Use vertical lines to create stem effect
631
- self._data.append({
632
- 'type': 'stem',
633
- 'x': x,
634
- 'y': y,
635
- 'color': color,
636
- 'orientation': orientation
637
- })
638
-
785
+ self._data.append(
786
+ {"type": "stem", "x": x, "y": y, "color": color, "orientation": orientation}
787
+ )
788
+
639
789
  def show(self):
640
790
  """Render and display the stem chart"""
641
791
  _core.clear_figure()
642
-
643
- if self._config['title']:
644
- _core.title(self._config['title'])
645
- if self._config['x_label']:
646
- _core.xlabel(self._config['x_label'])
647
- if self._config['y_label']:
648
- _core.ylabel(self._config['y_label'])
649
- if self._config['width'] or self._config['height']:
650
- _core.plot_size(self._config['width'], self._config['height'])
651
-
792
+
793
+ if self._config["title"]:
794
+ _core.title(self._config["title"])
795
+ if self._config["x_label"]:
796
+ _core.xlabel(self._config["x_label"])
797
+ if self._config["y_label"]:
798
+ _core.ylabel(self._config["y_label"])
799
+ if self._config["width"] or self._config["height"]:
800
+ _core.plot_size(self._config["width"], self._config["height"])
801
+
652
802
  for data_item in self._data:
653
- if data_item['type'] == 'stem':
803
+ if data_item["type"] == "stem":
654
804
  # Create stem plot using scatter points only for now
655
805
  # Full stem functionality would require extending core API
656
- _core.scatter(data_item['x'], data_item['y'],
657
- color=data_item['color'],
658
- marker='●') # Use solid dot for stem heads
659
-
806
+ _core.scatter(
807
+ data_item["x"], data_item["y"], color=data_item["color"], marker="●"
808
+ ) # Use solid dot for stem heads
809
+
660
810
  _core.show()
661
811
  return self
662
812
 
@@ -665,75 +815,77 @@ class Legend:
665
815
  """
666
816
  Legend class for adding legends to any chart type
667
817
  """
668
-
818
+
669
819
  def __init__(self):
670
820
  self.items = []
671
- self.position = 'upper right'
672
- self.style = 'box'
821
+ self.position = "upper right"
822
+ self.style = "box"
673
823
  self.show_border = True
674
-
824
+
675
825
  def add(self, label, color=None, marker=None, line_style=None):
676
826
  """
677
827
  Add an item to the legend
678
-
828
+
679
829
  Args:
680
830
  label (str): Text label for the legend item
681
831
  color (str): Color for the legend item
682
832
  marker (str): Marker style for the legend item
683
833
  line_style (str): Line style for the legend item
684
834
  """
685
- self.items.append({
686
- 'label': label,
687
- 'color': color or 'default',
688
- 'marker': marker or '■',
689
- 'line_style': line_style or 'solid'
690
- })
691
- return self
692
-
835
+ self.items.append(
836
+ {
837
+ "label": label,
838
+ "color": color or "default",
839
+ "marker": marker or "■",
840
+ "line_style": line_style or "solid",
841
+ }
842
+ )
843
+ return self
844
+
693
845
  def set_position(self, pos):
694
846
  """Set legend position ('upper right', 'upper left', 'lower right', 'lower left')"""
695
847
  self.position = pos
696
848
  return self
697
-
849
+
698
850
  def set_style(self, style_name):
699
851
  """Set legend style ('box', 'plain')"""
700
852
  self.style = style_name
701
853
  return self
702
-
854
+
703
855
  def set_border(self, show=True):
704
856
  """Show or hide legend border"""
705
857
  self.show_border = show
706
858
  return self
707
-
859
+
708
860
  def apply_to_chart(self, chart_instance):
709
861
  """Apply this legend to a chart instance"""
710
862
  # Set this legend as the chart's legend (replace any existing legend)
711
863
  chart_instance._legend = self
712
864
  return self
713
-
865
+
714
866
  def render_legend_text(self):
715
867
  """Generate legend text representation"""
716
868
  if not self.items:
717
869
  return []
718
-
870
+
719
871
  legend_lines = []
720
- if self.show_border and self.style == 'box':
872
+ if self.show_border and self.style == "box":
721
873
  legend_lines.append("┌─ Legend ─┐")
722
-
874
+
723
875
  for item in self.items:
724
- marker = item['marker']
725
- label = item['label']
876
+ marker = item["marker"]
877
+ label = item["label"]
726
878
  # Use color-coded markers if available
727
- if self.style == 'box':
879
+ if self.style == "box":
728
880
  legend_lines.append(f"│ {marker} {label}")
729
881
  else:
730
882
  legend_lines.append(f"{marker} {label}")
731
-
732
- if self.show_border and self.style == 'box':
883
+
884
+ if self.show_border and self.style == "box":
733
885
  legend_lines.append("└──────────┘")
734
-
886
+
735
887
  return legend_lines
736
-
888
+
737
889
  def show(self):
738
890
  """Display the legend independently"""
739
891
  legend_text = self.render_legend_text()
@@ -747,16 +899,34 @@ class PlotextAPI:
747
899
  Modern functional API that provides cleaner function-based interface
748
900
  while maintaining the flexibility of the original plotext.
749
901
  """
750
-
902
+
751
903
  @staticmethod
752
904
  def create_chart(use_banners=False, banner_title=None):
753
905
  """Create a new Chart instance"""
754
906
  return Chart(use_banners, banner_title)
755
-
907
+
756
908
  @staticmethod
757
- def quick_scatter(x, y, title=None, xlabel=None, ylabel=None, use_banners=False, banner_title=None):
909
+ def quick_scatter(
910
+ x,
911
+ y,
912
+ title=None,
913
+ xlabel=None,
914
+ ylabel=None,
915
+ theme_name=None,
916
+ use_banners=False,
917
+ banner_title=None,
918
+ ):
758
919
  """Quickly create and display a scatter plot"""
759
920
  chart = Chart(use_banners, banner_title)
921
+ if theme_name:
922
+ chart.theme(theme_name)
923
+
924
+ # Set chart size for better presentation
925
+ import plotext_plus._core as _core
926
+
927
+ term_width, term_height = _core.terminal_size()
928
+ chart.size(min(term_width, 120), max(20, term_height - 4))
929
+
760
930
  chart.scatter(x, y)
761
931
  if title:
762
932
  chart.title(title)
@@ -766,11 +936,29 @@ class PlotextAPI:
766
936
  chart.ylabel(ylabel)
767
937
  chart.show()
768
938
  return chart
769
-
939
+
770
940
  @staticmethod
771
- def quick_line(x, y, title=None, xlabel=None, ylabel=None, use_banners=False, banner_title=None):
941
+ def quick_line(
942
+ x,
943
+ y,
944
+ title=None,
945
+ xlabel=None,
946
+ ylabel=None,
947
+ theme_name=None,
948
+ use_banners=False,
949
+ banner_title=None,
950
+ ):
772
951
  """Quickly create and display a line plot"""
773
952
  chart = Chart(use_banners, banner_title)
953
+ if theme_name:
954
+ chart.theme(theme_name)
955
+
956
+ # Set chart size for better presentation
957
+ import plotext_plus._core as _core
958
+
959
+ term_width, term_height = _core.terminal_size()
960
+ chart.size(min(term_width, 120), max(20, term_height - 4))
961
+
774
962
  chart.line(x, y)
775
963
  if title:
776
964
  chart.title(title)
@@ -780,56 +968,129 @@ class PlotextAPI:
780
968
  chart.ylabel(ylabel)
781
969
  chart.show()
782
970
  return chart
783
-
971
+
784
972
  @staticmethod
785
- def quick_bar(labels, values, title=None, horizontal=False, use_banners=False, banner_title=None):
973
+ def quick_bar(
974
+ labels,
975
+ values,
976
+ title=None,
977
+ horizontal=False,
978
+ use_banners=False,
979
+ banner_title=None,
980
+ theme_name=None,
981
+ ):
786
982
  """Quickly create and display a bar chart"""
787
983
  chart = Chart(use_banners, banner_title)
984
+ if theme_name:
985
+ chart.theme(theme_name)
986
+
987
+ # Set chart size to use full terminal width for better presentation
988
+ import plotext_plus._core as _core
989
+
990
+ term_width, term_height = _core.terminal_size()
991
+ # Use a larger width to ensure the chart fills the available space
992
+ chart_width = min(
993
+ max(term_width, 100), 140
994
+ ) # At least 100, up to 140 characters wide
995
+ chart.size(chart_width, 20)
996
+
788
997
  chart.bar(labels, values, horizontal=horizontal)
789
998
  if title:
790
999
  chart.title(title)
791
1000
  chart.show()
792
1001
  return chart
793
-
794
- @staticmethod
795
- def quick_pie(labels, values, colors=None, title=None, use_banners=False, banner_title=None,
796
- show_values=True, show_percentages=True, show_values_on_slices=False, donut=False, remaining_color=None):
1002
+
1003
+ @staticmethod
1004
+ def quick_pie(
1005
+ labels,
1006
+ values,
1007
+ colors=None,
1008
+ title=None,
1009
+ use_banners=False,
1010
+ banner_title=None,
1011
+ show_values=True,
1012
+ show_percentages=True,
1013
+ show_values_on_slices=False,
1014
+ donut=False,
1015
+ remaining_color=None,
1016
+ theme_name=None,
1017
+ ):
797
1018
  """Quickly create and display a pie chart"""
798
1019
  chart = Chart(use_banners, banner_title)
799
- chart.pie(labels, values, colors=colors, show_values=show_values, show_percentages=show_percentages, show_values_on_slices=show_values_on_slices, donut=donut, remaining_color=remaining_color)
1020
+ if theme_name:
1021
+ chart.theme(theme_name)
1022
+
1023
+ # Set chart size for better presentation
1024
+ import plotext_plus._core as _core
1025
+
1026
+ term_width, term_height = _core.terminal_size()
1027
+ chart.size(min(term_width, 120), max(20, term_height - 4))
1028
+
1029
+ chart.pie(
1030
+ labels,
1031
+ values,
1032
+ colors=colors,
1033
+ show_values=show_values,
1034
+ show_percentages=show_percentages,
1035
+ show_values_on_slices=show_values_on_slices,
1036
+ donut=donut,
1037
+ remaining_color=remaining_color,
1038
+ )
800
1039
  if title:
801
1040
  chart.title(title)
802
1041
  chart.show()
803
1042
  return chart
804
-
1043
+
805
1044
  @staticmethod
806
- def quick_donut(labels, values, colors=None, title=None, use_banners=False, banner_title=None,
807
- show_values=True, show_percentages=True, show_values_on_slices=False, remaining_color=None):
1045
+ def quick_donut(
1046
+ labels,
1047
+ values,
1048
+ colors=None,
1049
+ title=None,
1050
+ use_banners=False,
1051
+ banner_title=None,
1052
+ show_values=True,
1053
+ show_percentages=True,
1054
+ show_values_on_slices=False,
1055
+ remaining_color=None,
1056
+ theme_name=None,
1057
+ ):
808
1058
  """Quickly create and display a doughnut chart"""
809
- return api.quick_pie(labels, values, colors=colors, title=title, use_banners=use_banners,
810
- banner_title=banner_title, show_values=show_values,
811
- show_percentages=show_percentages, show_values_on_slices=show_values_on_slices, donut=True, remaining_color=remaining_color)
812
-
1059
+ return PlotextAPI.quick_pie(
1060
+ labels,
1061
+ values,
1062
+ colors=colors,
1063
+ title=title,
1064
+ use_banners=use_banners,
1065
+ banner_title=banner_title,
1066
+ show_values=show_values,
1067
+ show_percentages=show_percentages,
1068
+ show_values_on_slices=show_values_on_slices,
1069
+ donut=True,
1070
+ remaining_color=remaining_color,
1071
+ theme_name=theme_name,
1072
+ )
1073
+
813
1074
  @staticmethod
814
1075
  def enable_banners(enabled=True, default_title="Plotext Chart"):
815
1076
  """Globally enable or disable banner mode"""
816
1077
  set_output_mode(enabled, default_title)
817
-
1078
+
818
1079
  @staticmethod
819
1080
  def log_info(message):
820
1081
  """Output info message using chuk-term"""
821
1082
  info(message)
822
-
1083
+
823
1084
  @staticmethod
824
1085
  def log_success(message):
825
1086
  """Output success message using chuk-term"""
826
1087
  success(message)
827
-
1088
+
828
1089
  @staticmethod
829
1090
  def log_warning(message):
830
1091
  """Output warning message using chuk-term"""
831
1092
  warning(message)
832
-
1093
+
833
1094
  @staticmethod
834
1095
  def log_error(message):
835
1096
  """Output error message using chuk-term"""
@@ -854,26 +1115,26 @@ log_error = api.log_error
854
1115
 
855
1116
  # Export specialized chart classes
856
1117
  __all__ = [
857
- 'Chart',
858
- 'ScatterChart',
859
- 'LineChart',
860
- 'BarChart',
861
- 'HistogramChart',
862
- 'CandlestickChart',
863
- 'HeatmapChart',
864
- 'MatrixChart',
865
- 'StemChart',
866
- 'Legend',
867
- 'PlotextAPI',
868
- 'create_chart',
869
- 'quick_scatter',
870
- 'quick_line',
871
- 'quick_bar',
872
- 'quick_pie',
873
- 'quick_donut',
874
- 'enable_banners',
875
- 'log_info',
876
- 'log_success',
877
- 'log_warning',
878
- 'log_error'
879
- ]
1118
+ "Chart",
1119
+ "ScatterChart",
1120
+ "LineChart",
1121
+ "BarChart",
1122
+ "HistogramChart",
1123
+ "CandlestickChart",
1124
+ "HeatmapChart",
1125
+ "MatrixChart",
1126
+ "StemChart",
1127
+ "Legend",
1128
+ "PlotextAPI",
1129
+ "create_chart",
1130
+ "quick_scatter",
1131
+ "quick_line",
1132
+ "quick_bar",
1133
+ "quick_pie",
1134
+ "quick_donut",
1135
+ "enable_banners",
1136
+ "log_info",
1137
+ "log_success",
1138
+ "log_warning",
1139
+ "log_error",
1140
+ ]