plotmind 0.1.0__tar.gz
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.
- plotmind-0.1.0/LICENSE +21 -0
- plotmind-0.1.0/MANIFEST.in +3 -0
- plotmind-0.1.0/PKG-INFO +255 -0
- plotmind-0.1.0/README.md +220 -0
- plotmind-0.1.0/plotmind/__init__.py +13 -0
- plotmind-0.1.0/plotmind/cleaner.py +68 -0
- plotmind-0.1.0/plotmind/cli.py +112 -0
- plotmind-0.1.0/plotmind/detector.py +67 -0
- plotmind-0.1.0/plotmind/exporter.py +111 -0
- plotmind-0.1.0/plotmind/loader.py +43 -0
- plotmind-0.1.0/plotmind/plotter.py +217 -0
- plotmind-0.1.0/plotmind/recommender.py +106 -0
- plotmind-0.1.0/plotmind/utils.py +56 -0
- plotmind-0.1.0/plotmind.egg-info/PKG-INFO +255 -0
- plotmind-0.1.0/plotmind.egg-info/SOURCES.txt +22 -0
- plotmind-0.1.0/plotmind.egg-info/dependency_links.txt +1 -0
- plotmind-0.1.0/plotmind.egg-info/entry_points.txt +2 -0
- plotmind-0.1.0/plotmind.egg-info/requires.txt +13 -0
- plotmind-0.1.0/plotmind.egg-info/top_level.txt +3 -0
- plotmind-0.1.0/pyproject.toml +40 -0
- plotmind-0.1.0/setup.cfg +4 -0
- plotmind-0.1.0/setup.py +45 -0
- plotmind-0.1.0/tests/__init__.py +0 -0
- plotmind-0.1.0/tests/test_plotmind.py +252 -0
plotmind-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 PlotMind Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
plotmind-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: plotmind
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Convert any CSV into meaningful graphs automatically.
|
|
5
|
+
Home-page: https://github.com/yourusername/plotmind
|
|
6
|
+
Author: PlotMind Contributors
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/yourusername/plotmind
|
|
9
|
+
Project-URL: Issues, https://github.com/yourusername/plotmind/issues
|
|
10
|
+
Keywords: csv,visualization,charts,graphs,data,plotly,matplotlib
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: pandas>=1.3.0
|
|
21
|
+
Requires-Dist: plotly>=5.0.0
|
|
22
|
+
Requires-Dist: matplotlib>=3.4.0
|
|
23
|
+
Requires-Dist: kaleido>=0.2.1
|
|
24
|
+
Provides-Extra: seaborn
|
|
25
|
+
Requires-Dist: seaborn>=0.11.0; extra == "seaborn"
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
29
|
+
Requires-Dist: black; extra == "dev"
|
|
30
|
+
Requires-Dist: flake8; extra == "dev"
|
|
31
|
+
Dynamic: author
|
|
32
|
+
Dynamic: home-page
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
Dynamic: requires-python
|
|
35
|
+
|
|
36
|
+
# PlotMind 📊
|
|
37
|
+
|
|
38
|
+
> **Convert any CSV into meaningful graphs automatically.**
|
|
39
|
+
|
|
40
|
+
PlotMind analyses your CSV, detects column types, recommends the best chart, and generates it — with zero manual configuration. It supports interactive charts via Plotly and static charts via Matplotlib, and can export to PNG, PDF, or HTML.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install plotmind
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or install from source:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/yourusername/plotmind
|
|
54
|
+
cd plotmind
|
|
55
|
+
pip install -e .
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Quick Start
|
|
61
|
+
|
|
62
|
+
### Python API
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from plotmind import load_csv, clean_dataframe, plot, export
|
|
66
|
+
|
|
67
|
+
# 1. Load
|
|
68
|
+
df = load_csv("sales.csv")
|
|
69
|
+
|
|
70
|
+
# 2. Clean (handles missing values, duplicates, type coercion)
|
|
71
|
+
df = clean_dataframe(df, verbose=True)
|
|
72
|
+
|
|
73
|
+
# 3. Plot – auto-detects best chart
|
|
74
|
+
fig = plot(df)
|
|
75
|
+
|
|
76
|
+
# 4. Export
|
|
77
|
+
export(fig, "sales_chart.html")
|
|
78
|
+
export(fig, "sales_chart.png")
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Command-Line Interface
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Auto-detect best chart and display
|
|
85
|
+
plotmind sales.csv
|
|
86
|
+
|
|
87
|
+
# Choose a specific chart type
|
|
88
|
+
plotmind sales.csv --chart bar
|
|
89
|
+
|
|
90
|
+
# Specify axes
|
|
91
|
+
plotmind sales.csv --chart scatter --x revenue --y profit
|
|
92
|
+
|
|
93
|
+
# Export to file without displaying
|
|
94
|
+
plotmind sales.csv --chart line --export output.html
|
|
95
|
+
|
|
96
|
+
# Use matplotlib backend
|
|
97
|
+
plotmind sales.csv --backend matplotlib --export chart.png
|
|
98
|
+
|
|
99
|
+
# Show column info and recommendation
|
|
100
|
+
plotmind sales.csv --info
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Features
|
|
106
|
+
|
|
107
|
+
| Feature | Description |
|
|
108
|
+
|---|---|
|
|
109
|
+
| **Auto-chart selection** | Detects the best chart based on column types |
|
|
110
|
+
| **Column type detection** | Identifies numerical, categorical, datetime, boolean columns |
|
|
111
|
+
| **Data cleaning** | Fills missing values, removes duplicates, fixes types |
|
|
112
|
+
| **Interactive charts** | Plotly backend for zoom/hover/pan |
|
|
113
|
+
| **Static charts** | Matplotlib backend for PNG/PDF output |
|
|
114
|
+
| **Export** | PNG, PDF, HTML, SVG |
|
|
115
|
+
| **CLI** | Full command-line interface |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Chart Types
|
|
120
|
+
|
|
121
|
+
PlotMind supports these chart types (auto-selected or manually chosen):
|
|
122
|
+
|
|
123
|
+
| Chart | When auto-selected |
|
|
124
|
+
|---|---|
|
|
125
|
+
| `histogram` | Single numerical column |
|
|
126
|
+
| `bar` | Categorical + numerical (high cardinality) |
|
|
127
|
+
| `pie` | Categorical + numerical (≤6 unique categories) |
|
|
128
|
+
| `scatter` | Two numerical columns |
|
|
129
|
+
| `line` | Datetime + numerical |
|
|
130
|
+
| `heatmap` | Many numerical columns (correlation matrix) |
|
|
131
|
+
| `box` | Box plot for distribution |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## API Reference
|
|
136
|
+
|
|
137
|
+
### `load_csv(filepath, **kwargs) → DataFrame`
|
|
138
|
+
Load a CSV and validate it.
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
df = load_csv("data.csv")
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### `clean_dataframe(df, verbose=False) → DataFrame`
|
|
147
|
+
Clean: fill missing values, remove duplicates, coerce types.
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
df = clean_dataframe(df, verbose=True)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### `detect_columns(df) → dict`
|
|
156
|
+
Return a dict of `{column_name: type}` for each column.
|
|
157
|
+
Types: `numerical`, `categorical`, `datetime`, `boolean`, `unknown`.
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from plotmind import detect_columns
|
|
161
|
+
types = detect_columns(df)
|
|
162
|
+
# {'age': 'numerical', 'city': 'categorical', ...}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### `recommend_chart(df, x=None, y=None) → (chart, x_col, y_col)`
|
|
168
|
+
Recommend the best chart. Returns a tuple.
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from plotmind import recommend_chart
|
|
172
|
+
chart, x, y = recommend_chart(df)
|
|
173
|
+
print(chart) # e.g. 'scatter'
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### `plot(df, chart=None, x=None, y=None, title=None, backend='plotly', show=True) → Figure`
|
|
179
|
+
Generate a chart. Returns the figure object.
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
fig = plot(df, chart="bar", x="city", y="sales", title="Sales by City")
|
|
183
|
+
fig = plot(df, backend="matplotlib", show=False) # static, no display
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### `export(fig, path, fmt=None) → str`
|
|
189
|
+
Export the figure. Format is inferred from the file extension.
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
export(fig, "chart.png") # PNG (requires kaleido for Plotly)
|
|
193
|
+
export(fig, "chart.pdf") # PDF
|
|
194
|
+
export(fig, "chart.html") # Interactive HTML (Plotly) or embedded HTML (Matplotlib)
|
|
195
|
+
export(fig, "chart.svg") # SVG
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Utils
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
from plotmind.utils import preview, column_stats, filter_columns
|
|
204
|
+
|
|
205
|
+
preview(df) # Print head
|
|
206
|
+
column_stats(df) # Summary DataFrame with null counts, unique values, etc.
|
|
207
|
+
filter_columns(df, types=["number"]) # Get only numeric column names
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Testing
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
pip install plotmind[dev]
|
|
216
|
+
pytest tests/ -v
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Requirements
|
|
222
|
+
|
|
223
|
+
- Python ≥ 3.8
|
|
224
|
+
- pandas ≥ 1.3
|
|
225
|
+
- plotly ≥ 5.0
|
|
226
|
+
- matplotlib ≥ 3.4
|
|
227
|
+
- kaleido ≥ 0.2.1 *(for Plotly static image export)*
|
|
228
|
+
|
|
229
|
+
Optional:
|
|
230
|
+
- seaborn *(for nicer heatmaps with `pip install plotmind[seaborn]`)*
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Publishing to PyPI
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
pip install build twine
|
|
238
|
+
python -m build
|
|
239
|
+
twine upload dist/*
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Roadmap
|
|
245
|
+
|
|
246
|
+
- **v0.2** – CLI improvements + test coverage
|
|
247
|
+
- **v0.3** – Docs + PyPI release
|
|
248
|
+
- **v0.4** – AI prompt-based visualization (`plot(df, prompt="Show me trends over time")`)
|
|
249
|
+
- **v0.5** – Smart dashboards & auto-insights
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## License
|
|
254
|
+
|
|
255
|
+
MIT
|
plotmind-0.1.0/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# PlotMind 📊
|
|
2
|
+
|
|
3
|
+
> **Convert any CSV into meaningful graphs automatically.**
|
|
4
|
+
|
|
5
|
+
PlotMind analyses your CSV, detects column types, recommends the best chart, and generates it — with zero manual configuration. It supports interactive charts via Plotly and static charts via Matplotlib, and can export to PNG, PDF, or HTML.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install plotmind
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or install from source:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git clone https://github.com/yourusername/plotmind
|
|
19
|
+
cd plotmind
|
|
20
|
+
pip install -e .
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### Python API
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from plotmind import load_csv, clean_dataframe, plot, export
|
|
31
|
+
|
|
32
|
+
# 1. Load
|
|
33
|
+
df = load_csv("sales.csv")
|
|
34
|
+
|
|
35
|
+
# 2. Clean (handles missing values, duplicates, type coercion)
|
|
36
|
+
df = clean_dataframe(df, verbose=True)
|
|
37
|
+
|
|
38
|
+
# 3. Plot – auto-detects best chart
|
|
39
|
+
fig = plot(df)
|
|
40
|
+
|
|
41
|
+
# 4. Export
|
|
42
|
+
export(fig, "sales_chart.html")
|
|
43
|
+
export(fig, "sales_chart.png")
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Command-Line Interface
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Auto-detect best chart and display
|
|
50
|
+
plotmind sales.csv
|
|
51
|
+
|
|
52
|
+
# Choose a specific chart type
|
|
53
|
+
plotmind sales.csv --chart bar
|
|
54
|
+
|
|
55
|
+
# Specify axes
|
|
56
|
+
plotmind sales.csv --chart scatter --x revenue --y profit
|
|
57
|
+
|
|
58
|
+
# Export to file without displaying
|
|
59
|
+
plotmind sales.csv --chart line --export output.html
|
|
60
|
+
|
|
61
|
+
# Use matplotlib backend
|
|
62
|
+
plotmind sales.csv --backend matplotlib --export chart.png
|
|
63
|
+
|
|
64
|
+
# Show column info and recommendation
|
|
65
|
+
plotmind sales.csv --info
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Features
|
|
71
|
+
|
|
72
|
+
| Feature | Description |
|
|
73
|
+
|---|---|
|
|
74
|
+
| **Auto-chart selection** | Detects the best chart based on column types |
|
|
75
|
+
| **Column type detection** | Identifies numerical, categorical, datetime, boolean columns |
|
|
76
|
+
| **Data cleaning** | Fills missing values, removes duplicates, fixes types |
|
|
77
|
+
| **Interactive charts** | Plotly backend for zoom/hover/pan |
|
|
78
|
+
| **Static charts** | Matplotlib backend for PNG/PDF output |
|
|
79
|
+
| **Export** | PNG, PDF, HTML, SVG |
|
|
80
|
+
| **CLI** | Full command-line interface |
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Chart Types
|
|
85
|
+
|
|
86
|
+
PlotMind supports these chart types (auto-selected or manually chosen):
|
|
87
|
+
|
|
88
|
+
| Chart | When auto-selected |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `histogram` | Single numerical column |
|
|
91
|
+
| `bar` | Categorical + numerical (high cardinality) |
|
|
92
|
+
| `pie` | Categorical + numerical (≤6 unique categories) |
|
|
93
|
+
| `scatter` | Two numerical columns |
|
|
94
|
+
| `line` | Datetime + numerical |
|
|
95
|
+
| `heatmap` | Many numerical columns (correlation matrix) |
|
|
96
|
+
| `box` | Box plot for distribution |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## API Reference
|
|
101
|
+
|
|
102
|
+
### `load_csv(filepath, **kwargs) → DataFrame`
|
|
103
|
+
Load a CSV and validate it.
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
df = load_csv("data.csv")
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### `clean_dataframe(df, verbose=False) → DataFrame`
|
|
112
|
+
Clean: fill missing values, remove duplicates, coerce types.
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
df = clean_dataframe(df, verbose=True)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### `detect_columns(df) → dict`
|
|
121
|
+
Return a dict of `{column_name: type}` for each column.
|
|
122
|
+
Types: `numerical`, `categorical`, `datetime`, `boolean`, `unknown`.
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from plotmind import detect_columns
|
|
126
|
+
types = detect_columns(df)
|
|
127
|
+
# {'age': 'numerical', 'city': 'categorical', ...}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
### `recommend_chart(df, x=None, y=None) → (chart, x_col, y_col)`
|
|
133
|
+
Recommend the best chart. Returns a tuple.
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from plotmind import recommend_chart
|
|
137
|
+
chart, x, y = recommend_chart(df)
|
|
138
|
+
print(chart) # e.g. 'scatter'
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### `plot(df, chart=None, x=None, y=None, title=None, backend='plotly', show=True) → Figure`
|
|
144
|
+
Generate a chart. Returns the figure object.
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
fig = plot(df, chart="bar", x="city", y="sales", title="Sales by City")
|
|
148
|
+
fig = plot(df, backend="matplotlib", show=False) # static, no display
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### `export(fig, path, fmt=None) → str`
|
|
154
|
+
Export the figure. Format is inferred from the file extension.
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
export(fig, "chart.png") # PNG (requires kaleido for Plotly)
|
|
158
|
+
export(fig, "chart.pdf") # PDF
|
|
159
|
+
export(fig, "chart.html") # Interactive HTML (Plotly) or embedded HTML (Matplotlib)
|
|
160
|
+
export(fig, "chart.svg") # SVG
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Utils
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from plotmind.utils import preview, column_stats, filter_columns
|
|
169
|
+
|
|
170
|
+
preview(df) # Print head
|
|
171
|
+
column_stats(df) # Summary DataFrame with null counts, unique values, etc.
|
|
172
|
+
filter_columns(df, types=["number"]) # Get only numeric column names
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Testing
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
pip install plotmind[dev]
|
|
181
|
+
pytest tests/ -v
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Requirements
|
|
187
|
+
|
|
188
|
+
- Python ≥ 3.8
|
|
189
|
+
- pandas ≥ 1.3
|
|
190
|
+
- plotly ≥ 5.0
|
|
191
|
+
- matplotlib ≥ 3.4
|
|
192
|
+
- kaleido ≥ 0.2.1 *(for Plotly static image export)*
|
|
193
|
+
|
|
194
|
+
Optional:
|
|
195
|
+
- seaborn *(for nicer heatmaps with `pip install plotmind[seaborn]`)*
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Publishing to PyPI
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
pip install build twine
|
|
203
|
+
python -m build
|
|
204
|
+
twine upload dist/*
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Roadmap
|
|
210
|
+
|
|
211
|
+
- **v0.2** – CLI improvements + test coverage
|
|
212
|
+
- **v0.3** – Docs + PyPI release
|
|
213
|
+
- **v0.4** – AI prompt-based visualization (`plot(df, prompt="Show me trends over time")`)
|
|
214
|
+
- **v0.5** – Smart dashboards & auto-insights
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PlotMind – Convert any CSV into meaningful graphs automatically.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .loader import load_csv
|
|
6
|
+
from .cleaner import clean_dataframe
|
|
7
|
+
from .detector import detect_columns
|
|
8
|
+
from .recommender import recommend_chart
|
|
9
|
+
from .plotter import plot
|
|
10
|
+
from .exporter import export
|
|
11
|
+
|
|
12
|
+
__version__ = "0.1.0"
|
|
13
|
+
__all__ = ["load_csv", "clean_dataframe", "detect_columns", "recommend_chart", "plot", "export"]
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
cleaner.py – Handles missing values, duplicates, and data type fixes.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def clean_dataframe(df: pd.DataFrame, verbose: bool = False) -> pd.DataFrame:
|
|
9
|
+
"""
|
|
10
|
+
Clean a DataFrame by handling missing values, duplicates, and data types.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
df: Input DataFrame.
|
|
14
|
+
verbose: If True, prints a cleaning summary.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
A cleaned copy of the DataFrame.
|
|
18
|
+
"""
|
|
19
|
+
df = df.copy()
|
|
20
|
+
report = {}
|
|
21
|
+
|
|
22
|
+
# --- Remove duplicate rows ---
|
|
23
|
+
before = len(df)
|
|
24
|
+
df = df.drop_duplicates()
|
|
25
|
+
report["duplicates_removed"] = before - len(df)
|
|
26
|
+
|
|
27
|
+
# --- Fix data types: try numeric coercion on object columns ---
|
|
28
|
+
for col in df.select_dtypes(include=["object", "string"]).columns:
|
|
29
|
+
# Try parsing as datetime first
|
|
30
|
+
try:
|
|
31
|
+
parsed = pd.to_datetime(df[col], infer_datetime_format=True)
|
|
32
|
+
if parsed.notna().sum() > len(df) * 0.5:
|
|
33
|
+
df[col] = parsed
|
|
34
|
+
continue
|
|
35
|
+
except Exception:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
# Try parsing as numeric
|
|
39
|
+
coerced = pd.to_numeric(df[col], errors="coerce")
|
|
40
|
+
if coerced.notna().sum() > len(df) * 0.5:
|
|
41
|
+
df[col] = coerced
|
|
42
|
+
continue
|
|
43
|
+
|
|
44
|
+
# --- Handle missing values ---
|
|
45
|
+
missing_before = df.isnull().sum().sum()
|
|
46
|
+
|
|
47
|
+
for col in df.columns:
|
|
48
|
+
if df[col].isnull().sum() == 0:
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
if pd.api.types.is_numeric_dtype(df[col]):
|
|
52
|
+
df[col] = df[col].fillna(df[col].median())
|
|
53
|
+
elif pd.api.types.is_datetime64_any_dtype(df[col]):
|
|
54
|
+
df[col] = df[col].fillna(method="ffill").fillna(method="bfill")
|
|
55
|
+
else:
|
|
56
|
+
mode = df[col].mode()
|
|
57
|
+
fill_val = mode[0] if not mode.empty else "Unknown"
|
|
58
|
+
df[col] = df[col].fillna(fill_val)
|
|
59
|
+
|
|
60
|
+
report["missing_filled"] = missing_before
|
|
61
|
+
|
|
62
|
+
if verbose:
|
|
63
|
+
print("[PlotMind Cleaner]")
|
|
64
|
+
print(f" Duplicates removed : {report['duplicates_removed']}")
|
|
65
|
+
print(f" Missing values filled : {report['missing_filled']}")
|
|
66
|
+
print(f" Final shape : {df.shape}")
|
|
67
|
+
|
|
68
|
+
return df
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
cli.py – Command-line interface for PlotMind.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
plotmind data.csv
|
|
6
|
+
plotmind data.csv --chart bar
|
|
7
|
+
plotmind data.csv --chart scatter --x col1 --y col2
|
|
8
|
+
plotmind data.csv --chart line --export output.html
|
|
9
|
+
plotmind data.csv --backend matplotlib --export chart.png
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import argparse
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
from .loader import load_csv
|
|
16
|
+
from .cleaner import clean_dataframe
|
|
17
|
+
from .recommender import recommend_chart, CHART_TYPES
|
|
18
|
+
from .plotter import plot
|
|
19
|
+
from .exporter import export
|
|
20
|
+
from .detector import summarize_columns
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main():
|
|
24
|
+
parser = argparse.ArgumentParser(
|
|
25
|
+
prog="plotmind",
|
|
26
|
+
description="PlotMind – Convert any CSV into meaningful graphs automatically.",
|
|
27
|
+
)
|
|
28
|
+
parser.add_argument("csv", help="Path to the CSV file")
|
|
29
|
+
parser.add_argument(
|
|
30
|
+
"--chart", "-c",
|
|
31
|
+
choices=CHART_TYPES,
|
|
32
|
+
default=None,
|
|
33
|
+
help="Chart type (default: auto-recommended)",
|
|
34
|
+
)
|
|
35
|
+
parser.add_argument("--x", default=None, help="Column for x-axis")
|
|
36
|
+
parser.add_argument("--y", default=None, help="Column for y-axis")
|
|
37
|
+
parser.add_argument(
|
|
38
|
+
"--export", "-e",
|
|
39
|
+
default=None,
|
|
40
|
+
metavar="FILE",
|
|
41
|
+
help="Export path (e.g. chart.png, chart.html, chart.pdf)",
|
|
42
|
+
)
|
|
43
|
+
parser.add_argument(
|
|
44
|
+
"--backend",
|
|
45
|
+
choices=["plotly", "matplotlib"],
|
|
46
|
+
default="plotly",
|
|
47
|
+
help="Rendering backend (default: plotly)",
|
|
48
|
+
)
|
|
49
|
+
parser.add_argument(
|
|
50
|
+
"--no-clean",
|
|
51
|
+
action="store_true",
|
|
52
|
+
help="Skip data cleaning step",
|
|
53
|
+
)
|
|
54
|
+
parser.add_argument(
|
|
55
|
+
"--info",
|
|
56
|
+
action="store_true",
|
|
57
|
+
help="Show column type info and exit",
|
|
58
|
+
)
|
|
59
|
+
parser.add_argument(
|
|
60
|
+
"--title",
|
|
61
|
+
default=None,
|
|
62
|
+
help="Custom chart title",
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
args = parser.parse_args()
|
|
66
|
+
|
|
67
|
+
# Load
|
|
68
|
+
try:
|
|
69
|
+
df = load_csv(args.csv)
|
|
70
|
+
print(f"[PlotMind] Loaded {args.csv} ({df.shape[0]} rows × {df.shape[1]} cols)")
|
|
71
|
+
except (FileNotFoundError, ValueError) as e:
|
|
72
|
+
print(f"[PlotMind] Error: {e}", file=sys.stderr)
|
|
73
|
+
sys.exit(1)
|
|
74
|
+
|
|
75
|
+
# Info mode
|
|
76
|
+
if args.info:
|
|
77
|
+
summarize_columns(df)
|
|
78
|
+
chart, x, y = recommend_chart(df, x=args.x, y=args.y)
|
|
79
|
+
print(f"\n[PlotMind] Recommended: {chart.upper()} x={x} y={y}")
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
# Clean
|
|
83
|
+
if not args.no_clean:
|
|
84
|
+
df = clean_dataframe(df, verbose=True)
|
|
85
|
+
|
|
86
|
+
# Plot
|
|
87
|
+
show = args.export is None # Only show interactively if not exporting
|
|
88
|
+
try:
|
|
89
|
+
fig = plot(
|
|
90
|
+
df,
|
|
91
|
+
chart=args.chart,
|
|
92
|
+
x=args.x,
|
|
93
|
+
y=args.y,
|
|
94
|
+
title=args.title,
|
|
95
|
+
backend=args.backend,
|
|
96
|
+
show=show,
|
|
97
|
+
)
|
|
98
|
+
except Exception as e:
|
|
99
|
+
print(f"[PlotMind] Plot error: {e}", file=sys.stderr)
|
|
100
|
+
sys.exit(1)
|
|
101
|
+
|
|
102
|
+
# Export
|
|
103
|
+
if args.export:
|
|
104
|
+
try:
|
|
105
|
+
export(fig, args.export)
|
|
106
|
+
except Exception as e:
|
|
107
|
+
print(f"[PlotMind] Export error: {e}", file=sys.stderr)
|
|
108
|
+
sys.exit(1)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
main()
|