jsongrapher 1.6__py3-none-any.whl → 2.8__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.
@@ -0,0 +1,125 @@
1
+ import unitpy
2
+ import unitpy.definitions
3
+ import unitpy.definitions.entry
4
+
5
+ print(unitpy.U("kg/m"))
6
+
7
+
8
+ print(unitpy.U("(((kg)/m))/s"))
9
+
10
+ units1 = unitpy.U("(((kg)/m))/s")
11
+ units2 = unitpy.U("(((g)/m))/s")
12
+ unitsRatio = units1/units2
13
+ print(unitsRatio)
14
+
15
+ print(units2)
16
+ units1multiplied =1*unitpy.U("(((kg)/m))/s")
17
+ print("line 14")
18
+ ratioWithUnits = units1multiplied.to("(((g)/m))/s")
19
+ print(ratioWithUnits)
20
+ print(str(ratioWithUnits).split(' '))
21
+
22
+ units1 = unitpy.Q("1 (((kg)/m))/s")
23
+ units2 = unitpy.Q("1 (((g)/m))/s")
24
+ print("line 22", units2.base_unit)
25
+ unitsRatio = units1/units2
26
+ print("line 23")
27
+ print(unitsRatio)
28
+
29
+
30
+
31
+ print(units2)
32
+ units1multiplied =1*unitpy.U("(((kg)/m))*(s**-1)")
33
+ print("line 14")
34
+ ratioWithUnits = units1multiplied.to("(((g)/m))/s")
35
+ print(ratioWithUnits)
36
+ print(str(ratioWithUnits).split(' '))
37
+ print(units1multiplied.base_unit)
38
+
39
+ units5 = unitpy.Q("1 (((g)/m))/s")
40
+ print(units5.base_unit)
41
+
42
+
43
+ def convert_inverse_units(expression, depth=100):
44
+ import re
45
+ # Patterns to match valid reciprocals while ignoring multiplied units
46
+ patterns = [r"1/\((1/.*?)\)", r"1/([a-zA-Z]+)"]
47
+
48
+ for _ in range(depth):
49
+ new_expression = expression
50
+ for pattern in patterns:
51
+ new_expression = re.sub(pattern, r"(\1)**(-1)", new_expression)
52
+
53
+ # Stop early if no more changes are made
54
+ if new_expression == expression:
55
+ break
56
+ expression = new_expression
57
+ return expression
58
+
59
+
60
+ expression_original = "1/(1/bar)"
61
+ expression_altered = convert_inverse_units(expression_original)
62
+ units6 = unitpy.Q('1*'+expression_altered)
63
+ print(units6.unit)
64
+
65
+ from unitpy import U, Unit
66
+ import unitpy
67
+ newunit = unitpy.Unit("meter")
68
+ from unitpy.definitions.entry import Entry
69
+ # new_entry = Entry("frog", "frog", "frog", 1.0)
70
+ # unitpy.ledger.add_unit(new_entry)
71
+ def add_custom_unit_to_unitpy(unit_string):
72
+ import unitpy
73
+ from unitpy.definitions.entry import Entry
74
+ #need to put an entry into "bases" because the BaseSet class will pull from that dictionary.
75
+ unitpy.definitions.unit_base.bases[unit_string] = unitpy.definitions.unit_base.BaseUnit(label=unit_string, abbr=unit_string,dimension=unitpy.definitions.dimensions.dimensions["amount_of_substance"])
76
+ #Then need to make a BaseSet object to put in. Confusingly, we *do not* put a BaseUnit object into the base_unit argument, below.
77
+ #We use "mole" to avoid conflicting with any other existing units.
78
+ base_unit =unitpy.definitions.unit_base.BaseSet(mole = 1)
79
+ #base_unit = unitpy.definitions.unit_base.BaseUnit(label=unit_string, abbr=unit_string,dimension=unitpy.definitions.dimensions.dimensions["amount_of_substance"])
80
+ new_entry = Entry(label = unit_string, abbr = unit_string, base_unit = base_unit, multiplier= 1)
81
+ #only add the entry if it is missing. A duplicate entry would cause crashing later.
82
+ if not unitpy.ledger.get_entry(new_entry):
83
+ unitpy.ledger.add_unit(new_entry) #implied return is here. No return needed.
84
+
85
+ add_custom_unit_to_unitpy("frog")
86
+ #TODO: now know one way how to add custom units to unitpy.
87
+ #Cannot put "<>" inside unitpy, but could filter those out, and then put them back. Would need to make a list of unique entries with <> because there could be more than one.
88
+
89
+ another_test = "1/bar/(1/bar)*bar*frog"
90
+ another_test = convert_inverse_units(another_test)
91
+ print("line 65", another_test)
92
+ units7 = unitpy.U(another_test)
93
+ print("line 66", units7)
94
+ print("line 86", 1*units7)
95
+ print(unitpy.ledger.get_entry("frog"))
96
+ units_string_1 = 'm*frog'
97
+ print("line 87", 1*unitpy.U(units_string_1))
98
+
99
+
100
+
101
+
102
+ print("line 94")
103
+
104
+ units_string_2 = 'm*frog'
105
+
106
+ units_string_1_multiplied = 1*unitpy.U(units_string_1 )
107
+ units_string_1_multiplied.to(units_string_2)
108
+
109
+
110
+ print(units2)
111
+ units1multiplied =1*unitpy.U("(((kg)/m))/s")
112
+ print("line 85")
113
+ string2 = "(((g)/m))*1/s"
114
+ string2 = convert_inverse_units(string2)
115
+ print(string2)
116
+ ratioWithUnits = units1multiplied.to(string2)
117
+ print(ratioWithUnits)
118
+ print(str(ratioWithUnits).split(' '))
119
+
120
+
121
+ #micrometer symbol, "μ" will result in error, also typing out "microm" will result in error, but "micrometer" works
122
+ units1 = unitpy.U("(((kg)/mm))/s")
123
+ #units2 = unitpy.U("(((g)/μm))/s")
124
+ #units2 = unitpy.U("(((g)/microm))/s")
125
+ units2 = unitpy.U("(((g)/micrometer))/s")
@@ -0,0 +1,28 @@
1
+ import unitpy
2
+ import re
3
+ from unitpy.definitions.entry import Entry
4
+
5
+ def add_custom_unit(unit_string):
6
+ # Need to put an entry into "bases" because the BaseSet class will pull from that dictionary.
7
+ unitpy.definitions.unit_base.bases[unit_string] = unitpy.definitions.unit_base.BaseUnit(
8
+ label=unit_string, abbr=unit_string, dimension=unitpy.definitions.dimensions.dimensions["amount_of_substance"]
9
+ )
10
+
11
+ # Then need to make a BaseSet object to put in. Confusingly, we *do not* put a BaseUnit object into the base_unit argument, below.
12
+ # We use "mole" to avoid conflicting with any other existing units.
13
+ base_unit = unitpy.definitions.unit_base.BaseSet(mole=1)
14
+
15
+ new_entry = Entry(label=unit_string, abbr=unit_string, base_unit=base_unit, multiplier=1)
16
+
17
+ # Only add the entry if it is missing. A duplicate entry would cause crashing later.
18
+ if 'frog' not in unitpy.ledger._lookup:
19
+ unitpy.ledger.add_unit(new_entry) # Implied return is here. No return needed.
20
+
21
+ add_custom_unit("frog")
22
+ add_custom_unit("frog")
23
+
24
+ units_string_1 = 'm*frog'
25
+ units_string_2 = 'm*frog'
26
+ units_string_1_multiplied = 1*unitpy.U(units_string_1 )
27
+ print("line 25", type(units_string_1_multiplied))
28
+ units_string_1_multiplied.to(units_string_2)
JSONGrapher/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  #Try to do things a bit like https://github.com/python/cpython/blob/master/Lib/collections/__init__.py
2
2
  #Except instead of putting things here directly in __init__, we'll import them so they are accessible by importing the module.
3
- from JSONGrapherRC.JSONRecordCreator import *
3
+ from JSONGrapher.JSONRecordCreator import *
@@ -0,0 +1,109 @@
1
+ import os
2
+ import tkinter as tk
3
+ from tkinter import filedialog
4
+ from tkinterdnd2 import DND_FILES, TkinterDnD
5
+
6
+
7
+ #The below class creates a window for dragging and dropping or browsing and selecting files
8
+ #And each time one or more file is added, the full file list and most recently added files will be passed to
9
+ #The function supplied by the user (function_for_after_file_addition)
10
+ #with the two variables passed being all_selected_file_paths, newly_added_file_paths
11
+ #This class **cannot** be initiated directly, it should initiated using the
12
+ #companion function create_and_launch
13
+ class DragDropApp:
14
+ def __init__(self, root, app_name = '', function_for_after_file_addition = None):
15
+ self.root = root
16
+ self.root.title(app_name)
17
+ self.function_for_after_file_addition = function_for_after_file_addition
18
+
19
+ # Enable native drag-and-drop capability
20
+ self.root.drop_target_register(DND_FILES)
21
+ self.root.dnd_bind("<<Drop>>", self.drop_files)
22
+
23
+ # Create a drop zone
24
+ self.drop_frame = tk.Label(root, text="Drag and drop files here \n\n Click End When Finished", bg="lightgray", width=50, height=10)
25
+ self.drop_frame.pack(pady=10)
26
+
27
+ # Create a listbox to display selected files
28
+ self.file_listbox = tk.Listbox(root, width=60, height=10)
29
+ self.file_listbox.pack(pady=10)
30
+
31
+ # Buttons for manual selection and finalizing selection
32
+ self.select_button = tk.Button(root, text="Select Files By Browsing", command=self.open_file_dialog)
33
+ self.select_button.pack(pady=5)
34
+
35
+ # Create a frame for the middle buttons
36
+ button_frame_middle = tk.Frame(root)
37
+ button_frame_middle.pack(pady=5)
38
+
39
+ self.clear_button = tk.Button(button_frame_middle, text="Clear Files List", command=self.clear_file_list) # New "Clear" button
40
+ self.clear_button.pack(side = tk.LEFT, pady=5)
41
+
42
+ # "Download Output" button
43
+ self.download_button = tk.Button(button_frame_middle, text="Download Output", command=self.download_output)
44
+ self.download_button.pack(side = tk.RIGHT, pady=5)
45
+
46
+ self.done_button = tk.Button(root, text="End", command=self.finish_selection)
47
+ self.done_button.pack(pady=5)
48
+
49
+ # Store selected file paths
50
+ self.all_selected_file_paths = []
51
+
52
+ def clear_file_list(self):
53
+ """Clears the listbox and resets selected files."""
54
+ self.file_listbox.delete(0, tk.END) # Clear listbox
55
+ self.all_selected_file_paths = [] # Reset file list
56
+ self.function_for_after_file_addition(all_selected_file_paths=[], newly_added_file_paths=[])
57
+ print("File list cleared!") # Optional debug message
58
+
59
+ def open_file_dialog(self):
60
+ """Opens a file dialog to manually select files."""
61
+ newly_added_file_paths = self.root.tk.splitlist(tk.filedialog.askopenfilenames(title="Select files"))
62
+ if newly_added_file_paths:
63
+ self.all_selected_file_paths.extend(newly_added_file_paths)
64
+ self.update_file_list(newly_added_file_paths)
65
+
66
+ def drop_files(self, event):
67
+ """Handles dropped files into the window."""
68
+ newly_added_file_paths = self.root.tk.splitlist(event.data)
69
+ if newly_added_file_paths:
70
+ self.all_selected_file_paths.extend(newly_added_file_paths)
71
+ self.update_file_list(newly_added_file_paths)
72
+
73
+ def update_file_list(self, newly_added_file_paths):
74
+ """Updates the listbox with selected filenames."""
75
+ self.file_listbox.delete(0, tk.END) # Clear listbox
76
+ for filename_and_path in self.all_selected_file_paths:
77
+ self.file_listbox.insert(tk.END, os.path.basename(filename_and_path)) # Show filenames only
78
+ # If there is a function_for_after_file_addition, pass full list and newly added files into function_for_after_file_addition
79
+ if self.function_for_after_file_addition is not None:
80
+ output = self.function_for_after_file_addition(self.all_selected_file_paths, newly_added_file_paths)
81
+ self.output_for_download = output[0] #store the first part of the output for download.
82
+
83
+ def download_output(self):
84
+ """Allows user to choose where to save the output."""
85
+ if hasattr(self, "output_for_download"):
86
+ file_path = filedialog.asksaveasfilename(filetypes=[("*.*", "*.txt")], title="Save Output As")
87
+ if file_path: # If a valid path is chosen
88
+ with open(file_path, "w") as file:
89
+ file.write(str(self.output_for_download))
90
+ print(f"Output saved as '{file_path}'!")
91
+ else:
92
+ print("File save operation canceled.")
93
+ else:
94
+ print("No output available to download.")
95
+
96
+
97
+ def finish_selection(self):
98
+ """Closes the window and returns selected files."""
99
+ self.root.quit() # Close the window
100
+
101
+ # This function is a companion function to
102
+ # The class DragDropApp for creating a file selection and function call app
103
+ # The function_for_after_file_addition should return a list where the first item is something that can be downloaded.
104
+ def create_and_launch(app_name = '', function_for_after_file_addition=None):
105
+ """Starts the GUI and returns selected files."""
106
+ root = TkinterDnD.Tk()
107
+ app = DragDropApp(root, app_name=app_name, function_for_after_file_addition=function_for_after_file_addition)
108
+ root.mainloop() # Runs the Tkinter event loop
109
+ return app.all_selected_file_paths # Returns selected files after the window closes
JSONGrapher/units_list.py CHANGED
@@ -2,6 +2,8 @@
2
2
  '''
3
3
  #This units list came from the UUC units list. https://github.com/Lemonexe/UUC/blob/master/app/data.js
4
4
  # it has been converted to python and contains all of the program constants, the unit database, and database of prefixes
5
+ #In the python JSONGrapher repository, this is used (as of May 2025) simply to remove "plural" units.
6
+ # In python JSONGrapher, the unitpy package is what is used for unit conversion.
5
7
  # 'en' is for English, 'cz' is for Czech, and "ae" is for American English.
6
8
 
7
9
  metre → meter
@@ -14,6 +16,31 @@
14
16
  tonne → metric ton (often written as ton in American English)
15
17
  cubic centimetre → cubic centimeter
16
18
 
19
+ This file is adapted from UUC and is covered by the MIT License
20
+
21
+ MIT License
22
+
23
+ Copyright (c) 2017 Jiri Zbytovsky
24
+
25
+ Permission is hereby granted, free of charge, to any person obtaining a copy
26
+ of this software and associated documentation files (the "Software"), to deal
27
+ in the Software without restriction, including without limitation the rights
28
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29
+ copies of the Software, and to permit persons to whom the Software is
30
+ furnished to do so, subject to the following conditions:
31
+
32
+ The above copyright notice and this permission notice shall be included in all
33
+ copies or substantial portions of the Software.
34
+
35
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41
+ SOFTWARE.
42
+
43
+
17
44
  '''
18
45
  import math as Math
19
46
  #program constants
@@ -1,79 +1,88 @@
1
- # JSONGrapherRC
2
- A python package for creating JSONGrapher Records
3
-
4
- To use JSONGrapherRC, first install it using pip:
5
- <pre>
6
- pip install JSONGrapherRC[COMPLETE]
7
- </pre>
8
-
9
- Alternatively, you can download the directory directly.<br>
10
- It is easiest to then follow the [example file](https://github.com/AdityaSavara/JSONGrapherRC/blob/main/example/exampleUsageJSONRecordCreator.py) to learn.<br>
11
-
12
-
13
- ## **1\. Preparing to Create a Record**
14
-
15
- Let's create an example where we plot the height of a pear tree over several years. Assuming a pear tree grows approximately 0.40 meters per year, we'll generate sample data with some variation.
16
- <pre>
17
- x_label_including_units = "Time (years)"
18
- y_label_including_units = "Height (m)"
19
- time_in_years = [0, 1, 2, 3, 4]
20
- tree_heights = [0, 0.42, 0.86, 1.19, 1.45]
21
- </pre>
22
-
23
- ## **2\. Creating and Populating a New JSONGrapher Record**
24
-
25
- The easiest way to start is with the `create_new_JSONGrapherRecord()` function. While you *can* instantiate the JSONGrapherRecord class directly, this function is generally more convenient. We'll create a record and inspect its default fields.
26
- <pre>
27
- try:
28
- from JSONGRapherRC import JSONRecordCreator # Normal usage
29
- except ImportError:
30
- import JSONRecordCreator # If the class file is local
31
-
32
- Record = JSONRecordCreator.create_new_JSONGrapherRecord()
33
- Record.set_comments("Tree Growth Data collected from the US National Arboretum")
34
- Record.set_datatype("Tree_Growth_Curve")
35
- Record.set_x_axis_label_including_units(x_label_including_units)
36
- Record.set_y_axis_label_including_units(y_label_including_units)
37
- Record.add_data_series(series_name="pear tree growth", x_values=time_in_years, y_values=tree_heights, plot_type="scatter_spline")
38
- Record.set_graph_title("Pear Tree Growth Versus Time")
39
- </pre>
40
-
41
- ## **3\. Exporting to File**
42
-
43
- We now have a JSONGrapher record! We can export it to a file, which can then be used with JSONGrapher.
44
- <pre>
45
- Record.export_to_json_file("ExampleFromTutorial.json")
46
- Record.print_to_inspect()
47
- </pre>
48
-
49
- <p><strong>Expected Output:</strong></p>
50
- <pre>
51
- JSONGrapher Record exported to, ./ExampleFromTutorial.json
52
- {
53
- "comments": "Tree Growth Data collected from the US National Arboretum",
54
- "datatype": "Tree_Growth_Curve",
55
- "data": [
56
- {
57
- "name": "pear tree growth",
58
- "x": [0, 1, 2, 3, 4],
59
- "y": [0, 0.42, 0.86, 1.19, 1.45],
60
- "type": "scatter",
61
- "line": { "shape": "spline" }
62
- }
63
- ],
64
- "layout": {
65
- "title": "Pear Tree Growth Versus Time",
66
- "xaxis": { "title": "Time (year)" },
67
- "yaxis": { "title": "Height (m)" }
68
- }
69
- }
70
- </pre>
71
-
72
-
73
- We can also plot the data using Matplotlib and export the plot as a PNG file.
74
- <pre>
75
- Record.plot_with_matplotlib()
76
- Record.export_to_matplotlib_png("ExampleFromTutorial")
77
- </pre>
78
-
79
- [![JSONGRapher record plotted using matplotlib](https://raw.githubusercontent.com/AdityaSavara/JSONGrapherRC/main/example/ExampleFromTutorial.png)](https://raw.githubusercontent.com/AdityaSavara/JSONGrapherRC/main/example/ExampleFromTutorial.png)
1
+ # JSONGrapher (python)
2
+ This is the python version of JSONGrapher with JSONRecordCreator. This package is for plotting JSON records with drag and drop and has tools for creating the JSON records.
3
+
4
+ To use python JSONGrapher, first install it using pip:
5
+ <pre>
6
+ pip install JSONGrapher[COMPLETE]
7
+ </pre>
8
+
9
+ Alternatively, you can download the directory directly.<br>
10
+
11
+ ## **0\. Plotting a JSON Record**
12
+ It's as simple as one line! Then drag a json record into the window to plot.
13
+ <pre>
14
+ import JSONGrapher
15
+ JSONGrapher.launch()
16
+ </pre>
17
+
18
+ [![JSONGRapher window](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/JSONGrapher/JSONGrapherWindowShortened.png)](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/JSONGrapher/JSONGrapherWindowShortened.png) [![JSONGRapher plot](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/examples/example_1/UAN_DTA_image.png)](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/examples/example_1/UAN_DTA_image.png)
19
+
20
+ ## **1\. Preparing to Create a Record**
21
+
22
+ The remainder of this landing page follows a json record tutorial [example file](https://github.com/AdityaSavara/JSONGrapher/blob/main/examples/example_2/example_2_json_record_tutorial.py) which shows how to create graphable .json records and to plot them. The .json files can then be dragged into the python JSONgrapher or into www.jsongrapher.com<br>
23
+
24
+ Let's create an example where we plot the height of a pear tree over several years. Assuming a pear tree grows approximately 0.40 meters per year, we'll generate sample data with some variation.
25
+ <pre>
26
+ x_label_including_units = "Time (years)"
27
+ y_label_including_units = "Height (m)"
28
+ time_in_years = [0, 1, 2, 3, 4]
29
+ tree_heights = [0, 0.42, 0.86, 1.19, 1.45]
30
+ </pre>
31
+
32
+ ## **2\. Creating and Populating a New JSONGrapher Record**
33
+
34
+ <pre>
35
+ Record = JSONRecordCreator.create_new_JSONGrapherRecord()
36
+ Record.set_comments("Tree Growth Data collected from the US National Arboretum")
37
+ Record.set_datatype("Tree_Growth_Curve")
38
+ Record.set_x_axis_label_including_units(x_label_including_units)
39
+ Record.set_y_axis_label_including_units(y_label_including_units)
40
+ Record.add_data_series(series_name="pear tree growth", x_values=time_in_years, y_values=tree_heights, plot_type="scatter_spline")
41
+ Record.set_graph_title("Pear Tree Growth Versus Time")
42
+ </pre>
43
+
44
+ ## **3\. Exporting to File**
45
+
46
+ We can export it to a .json file, which can then be used with JSONGrapher.
47
+ <pre>
48
+ Record.export_to_json_file("ExampleFromTutorial.json")
49
+ Record.print_to_inspect()
50
+ </pre>
51
+
52
+ <p><strong>Expected Output:</strong></p>
53
+ <pre>
54
+ JSONGrapher Record exported to, ./ExampleFromTutorial.json
55
+ {
56
+ "comments": "Tree Growth Data collected from the US National Arboretum",
57
+ "datatype": "Tree_Growth_Curve",
58
+ "data": [
59
+ {
60
+ "name": "pear tree growth",
61
+ "x": [0, 1, 2, 3, 4],
62
+ "y": [0, 0.42, 0.86, 1.19, 1.45],
63
+ "type": "scatter",
64
+ "line": { "shape": "spline" }
65
+ }
66
+ ],
67
+ "layout": {
68
+ "title": "Pear Tree Growth Versus Time",
69
+ "xaxis": { "title": "Time (year)" },
70
+ "yaxis": { "title": "Height (m)" }
71
+ }
72
+ }
73
+ </pre>
74
+
75
+ ## **4\. Plotting to Inspect**
76
+
77
+ We can also plot the data using Matplotlib and export the plot as a PNG file.
78
+ <pre>
79
+ Record.plot_with_matplotlib()
80
+ Record.export_to_matplotlib_png("image_from_tutorial_matplotlib_fig")
81
+ </pre>
82
+
83
+ And we can create an interactive graph with plotly:
84
+ <pre>
85
+ Record.plot_with_plotly() #Try hovering your mouse over points after this command!
86
+ </pre>
87
+
88
+ [![JSONGRapher record plotted using matplotlib](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/examples/example_2/image_from_tutorial_matplotlib_fig.png)](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/examples/example_2/image_from_tutorial_matplotlib_fig.png)
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jsongrapher
3
- Version: 1.6
4
- Summary: A python package for creating JSONGrapher Records.
5
- Home-page: https://github.com/AdityaSavara/JSONGrapherRC
3
+ Version: 2.8
4
+ Summary: The python version of JSONGrapher with tools for creating JSONGrapher Records.
5
+ Home-page: https://github.com/AdityaSavara/jsongrapher-py
6
6
  Author: Aditya Savara
7
7
  Author-email: AditySavara2008@u.northwestern.edu
8
8
  License: Unlicense
@@ -18,22 +18,34 @@ License-File: LICENSE
18
18
  Requires-Dist: numpy
19
19
  Provides-Extra: complete
20
20
  Requires-Dist: matplotlib; extra == "complete"
21
+ Requires-Dist: plotly; extra == "complete"
22
+ Requires-Dist: unitpy; extra == "complete"
23
+ Requires-Dist: tkinterdnd2; extra == "complete"
21
24
 
22
25
 
23
- # JSONGrapherRC
24
- A python package for creating JSONGrapher Records
26
+ # JSONGrapher (python)
27
+ This is the python version of JSONGrapher with JSONRecordCreator. This package is for plotting JSON records with drag and drop and has tools for creating the JSON records.
25
28
 
26
- To use JSONGrapherRC, first install it using pip:
29
+ To use python JSONGrapher, first install it using pip:
27
30
  <pre>
28
- pip install JSONGrapherRC[COMPLETE]
31
+ pip install JSONGrapher[COMPLETE]
29
32
  </pre>
30
33
 
31
34
  Alternatively, you can download the directory directly.<br>
32
- It is easiest to then follow the [example file](https://github.com/AdityaSavara/JSONGrapherRC/blob/main/example/exampleUsageJSONRecordCreator.py) to learn.<br>
33
35
 
36
+ ## **0\. Plotting a JSON Record**
37
+ It's as simple as one line! Then drag a json record into the window to plot.
38
+ <pre>
39
+ import JSONGrapher
40
+ JSONGrapher.launch()
41
+ </pre>
42
+
43
+ [![JSONGRapher window](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/JSONGrapher/JSONGrapherWindowShortened.png)](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/JSONGrapher/JSONGrapherWindowShortened.png) [![JSONGRapher plot](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/examples/example_1/UAN_DTA_image.png)](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/examples/example_1/UAN_DTA_image.png)
34
44
 
35
45
  ## **1\. Preparing to Create a Record**
36
46
 
47
+ The remainder of this landing page follows a json record tutorial [example file](https://github.com/AdityaSavara/JSONGrapher/blob/main/examples/example_2/example_2_json_record_tutorial.py) which shows how to create graphable .json records and to plot them. The .json files can then be dragged into the python JSONgrapher or into www.jsongrapher.com<br>
48
+
37
49
  Let's create an example where we plot the height of a pear tree over several years. Assuming a pear tree grows approximately 0.40 meters per year, we'll generate sample data with some variation.
38
50
  <pre>
39
51
  x_label_including_units = "Time (years)"
@@ -44,13 +56,7 @@ tree_heights = [0, 0.42, 0.86, 1.19, 1.45]
44
56
 
45
57
  ## **2\. Creating and Populating a New JSONGrapher Record**
46
58
 
47
- The easiest way to start is with the `create_new_JSONGrapherRecord()` function. While you *can* instantiate the JSONGrapherRecord class directly, this function is generally more convenient. We'll create a record and inspect its default fields.
48
59
  <pre>
49
- try:
50
- from JSONGRapherRC import JSONRecordCreator # Normal usage
51
- except ImportError:
52
- import JSONRecordCreator # If the class file is local
53
-
54
60
  Record = JSONRecordCreator.create_new_JSONGrapherRecord()
55
61
  Record.set_comments("Tree Growth Data collected from the US National Arboretum")
56
62
  Record.set_datatype("Tree_Growth_Curve")
@@ -62,7 +68,7 @@ Record.set_graph_title("Pear Tree Growth Versus Time")
62
68
 
63
69
  ## **3\. Exporting to File**
64
70
 
65
- We now have a JSONGrapher record! We can export it to a file, which can then be used with JSONGrapher.
71
+ We can export it to a .json file, which can then be used with JSONGrapher.
66
72
  <pre>
67
73
  Record.export_to_json_file("ExampleFromTutorial.json")
68
74
  Record.print_to_inspect()
@@ -91,11 +97,17 @@ JSONGrapher Record exported to, ./ExampleFromTutorial.json
91
97
  }
92
98
  </pre>
93
99
 
100
+ ## **4\. Plotting to Inspect**
94
101
 
95
102
  We can also plot the data using Matplotlib and export the plot as a PNG file.
96
103
  <pre>
97
104
  Record.plot_with_matplotlib()
98
- Record.export_to_matplotlib_png("ExampleFromTutorial")
105
+ Record.export_to_matplotlib_png("image_from_tutorial_matplotlib_fig")
106
+ </pre>
107
+
108
+ And we can create an interactive graph with plotly:
109
+ <pre>
110
+ Record.plot_with_plotly() #Try hovering your mouse over points after this command!
99
111
  </pre>
100
112
 
101
- [![JSONGRapher record plotted using matplotlib](https://raw.githubusercontent.com/AdityaSavara/JSONGrapherRC/main/example/ExampleFromTutorial.png)](https://raw.githubusercontent.com/AdityaSavara/JSONGrapherRC/main/example/ExampleFromTutorial.png)
113
+ [![JSONGRapher record plotted using matplotlib](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/examples/example_2/image_from_tutorial_matplotlib_fig.png)](https://raw.githubusercontent.com/AdityaSavara/JSONGrapher-py/main/examples/example_2/image_from_tutorial_matplotlib_fig.png)
@@ -0,0 +1,13 @@
1
+ JSONGrapher/JSONRecordCreator.py,sha256=rClBw0XfaGNx3LGwuT9gWwfW8TNzlnnZnaLbWqdsE9g,96177
2
+ JSONGrapher/UnitPytesting.py,sha256=xizJ-2fg9C5oNMFJyfavbBLMusayE9KWQiYIRrQQd4A,4363
3
+ JSONGrapher/UnitpyCustomUnitsTesting.py,sha256=Rwq5p8HXN0FP54lRFgLTV0kgJ9TpcFaD3_C0MEOoEzw,1297
4
+ JSONGrapher/__init__.py,sha256=cc5qXQidP_ABPXdnXy_DTdgPanHuR7ya45LV-BdWVh8,277
5
+ JSONGrapher/drag_and_drop_gui.py,sha256=-7QJHLhzadHotWhONH4inerMaZ_xuwoTQSMRF_MPVe0,5632
6
+ JSONGrapher/units_list.py,sha256=ROrlAsD66oPozZmOaE65xjNUEg3CxkSmA8iPE2_ihYI,34438
7
+ jsongrapher-2.8.data/data/LICENSE,sha256=KrPIO2Ij3T_47dfpfngKzpC4EXohIZMsHauG0R4M-kM,1234
8
+ jsongrapher-2.8.data/data/README.md,sha256=0gza4X7_6Sb7NAgeaiQfaizwmT7-PT_YsOHZMt0oQ_8,3921
9
+ jsongrapher-2.8.dist-info/LICENSE,sha256=KrPIO2Ij3T_47dfpfngKzpC4EXohIZMsHauG0R4M-kM,1234
10
+ jsongrapher-2.8.dist-info/METADATA,sha256=KfobXnAyNaLZV9fZuEUNYrQ6PcR090Ujhj2JHSSNnOg,4886
11
+ jsongrapher-2.8.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
12
+ jsongrapher-2.8.dist-info/top_level.txt,sha256=5f7Ui2hCKCPTQOjD540WKghKNYOvUDNfdpnDbIlAD3Y,12
13
+ jsongrapher-2.8.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- JSONGrapher/JSONRecordCreator.py,sha256=_dfVxwy7itw3mUq7G_akyeup5KEy6KHXLeiINAzhHqg,45957
2
- JSONGrapher/__init__.py,sha256=YvI9lnzN8e6jfCF--fuyiNZYq_YiVM72osipYjmWLAA,279
3
- JSONGrapher/units_list.py,sha256=ARlPgvKWZM8um1FA7OtzDjnJhl0zy1X4vGbTQN93MnQ,33074
4
- jsongrapher-1.6.data/data/LICENSE,sha256=KrPIO2Ij3T_47dfpfngKzpC4EXohIZMsHauG0R4M-kM,1234
5
- jsongrapher-1.6.data/data/README.md,sha256=9UIVwsfi9CtLWzRFTnMiWvRiFf7MZLzmlWOpuOrj8e8,3036
6
- jsongrapher-1.6.dist-info/LICENSE,sha256=KrPIO2Ij3T_47dfpfngKzpC4EXohIZMsHauG0R4M-kM,1234
7
- jsongrapher-1.6.dist-info/METADATA,sha256=sLXqe5taldI3P4ASryDjexbue9uH8p2bY3Gnb3nZvHw,3913
8
- jsongrapher-1.6.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
9
- jsongrapher-1.6.dist-info/top_level.txt,sha256=5f7Ui2hCKCPTQOjD540WKghKNYOvUDNfdpnDbIlAD3Y,12
10
- jsongrapher-1.6.dist-info/RECORD,,