jsongrapher 3.8__py3-none-any.whl → 3.9__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.
- JSONGrapher/JSONRecordCreator.py +70 -19
- {jsongrapher-3.8.dist-info → jsongrapher-3.9.dist-info}/METADATA +2 -2
- {jsongrapher-3.8.dist-info → jsongrapher-3.9.dist-info}/RECORD +8 -8
- {jsongrapher-3.8.data → jsongrapher-3.9.data}/data/LICENSE +0 -0
- {jsongrapher-3.8.data → jsongrapher-3.9.data}/data/README.md +0 -0
- {jsongrapher-3.8.dist-info → jsongrapher-3.9.dist-info}/LICENSE +0 -0
- {jsongrapher-3.8.dist-info → jsongrapher-3.9.dist-info}/WHEEL +0 -0
- {jsongrapher-3.8.dist-info → jsongrapher-3.9.dist-info}/top_level.txt +0 -0
JSONGrapher/JSONRecordCreator.py
CHANGED
@@ -831,6 +831,7 @@ class JSONGrapherRecord:
|
|
831
831
|
def evaluate_eqution_of_data_series_by_index(self, series_index, equation_dict = None, verbose=False):
|
832
832
|
if equation_dict != None:
|
833
833
|
self.fig_dict["data"][series_index]["equation"] = equation_dict
|
834
|
+
data_series_dict = self.fig_dict["data"][series_index]
|
834
835
|
self.fig_dict = evaluate_equation_for_data_series_by_index(data_series_index=data_series_dict, verbose=verbose) #implied return.
|
835
836
|
return data_series_dict #Extra regular return
|
836
837
|
|
@@ -842,11 +843,11 @@ class JSONGrapherRecord:
|
|
842
843
|
return self.fig_dict
|
843
844
|
#The update_and_validate function will clean for plotly.
|
844
845
|
#TODO: the internal recommending "print_to_inspect" function should, by default, exclude printing the full dictionaries of the layout_style and the trace_collection_style.
|
845
|
-
def print_to_inspect(self, update_and_validate=True, validate=True, remove_remaining_hints=False):
|
846
|
+
def print_to_inspect(self, update_and_validate=True, validate=True, clean_for_plotly = True, remove_remaining_hints=False):
|
846
847
|
if remove_remaining_hints == True:
|
847
848
|
self.remove_hints()
|
848
849
|
if update_and_validate == True: #this will do some automatic 'corrections' during the validation.
|
849
|
-
self.update_and_validate_JSONGrapher_record()
|
850
|
+
self.update_and_validate_JSONGrapher_record(clean_for_plotly=clean_for_plotly)
|
850
851
|
elif validate: #this will validate without doing automatic updates.
|
851
852
|
self.validate_JSONGrapher_record()
|
852
853
|
print(json.dumps(self.fig_dict, indent=4))
|
@@ -896,9 +897,7 @@ class JSONGrapherRecord:
|
|
896
897
|
#now, add the scaled data objects to the original one.
|
897
898
|
#This is fairly easy using a list extend.
|
898
899
|
self.fig_dict["data"].extend(scaled_fig_dict["data"])
|
899
|
-
|
900
|
-
|
901
|
-
|
900
|
+
|
902
901
|
def import_from_dict(self, fig_dict):
|
903
902
|
self.fig_dict = fig_dict
|
904
903
|
|
@@ -1047,7 +1046,7 @@ class JSONGrapherRecord:
|
|
1047
1046
|
elif validate: #this will validate without doing automatic updates.
|
1048
1047
|
self.validate_JSONGrapher_record()
|
1049
1048
|
|
1050
|
-
#
|
1049
|
+
# filename with path to save the JSON file.
|
1051
1050
|
if len(filename) > 0: #this means we will be writing to file.
|
1052
1051
|
# Check if the filename has an extension and append `.json` if not
|
1053
1052
|
if '.json' not in filename.lower():
|
@@ -1057,6 +1056,18 @@ class JSONGrapherRecord:
|
|
1057
1056
|
json.dump(self.fig_dict, f, indent=4)
|
1058
1057
|
return self.fig_dict
|
1059
1058
|
|
1059
|
+
def export_plotly_json(self, filename, plot_style = None, update_and_validate=True, simulate_all_series=True, evaluate_all_equations=True,adjust_implicit_data_ranges=True):
|
1060
|
+
fig = self.get_plotly_fig(plot_style=plot_style, update_and_validate=update_and_validate, simulate_all_series=simulate_all_series, evaluate_all_equations=evaluate_all_equations, adjust_implicit_data_ranges=adjust_implicit_data_ranges)
|
1061
|
+
plotly_json_string = fig.to_plotly_json()
|
1062
|
+
if len(filename) > 0: #this means we will be writing to file.
|
1063
|
+
# Check if the filename has an extension and append `.json` if not
|
1064
|
+
if '.json' not in filename.lower():
|
1065
|
+
filename += ".json"
|
1066
|
+
#Write to file using UTF-8 encoding.
|
1067
|
+
with open(filename, 'w', encoding='utf-8') as f:
|
1068
|
+
json.dump(plotly_json_string, f, indent=4)
|
1069
|
+
return plotly_json_string
|
1070
|
+
|
1060
1071
|
#simulate all series will simulate any series as needed.
|
1061
1072
|
def get_plotly_fig(self, plot_style=None, update_and_validate=True, simulate_all_series=True, evaluate_all_equations=True, adjust_implicit_data_ranges=True):
|
1062
1073
|
"""
|
@@ -1092,8 +1103,8 @@ class JSONGrapherRecord:
|
|
1092
1103
|
self.apply_plot_style(plot_style=plot_style)
|
1093
1104
|
#Now we clean out the fields and make a plotly object.
|
1094
1105
|
if update_and_validate == True: #this will do some automatic 'corrections' during the validation.
|
1095
|
-
self.update_and_validate_JSONGrapher_record() #
|
1096
|
-
self.fig_dict = clean_json_fig_dict(self.fig_dict, fields_to_update=['simulate', 'custom_units_chevrons', 'equation', 'trace_style', '3d_axes', 'bubble'])
|
1106
|
+
self.update_and_validate_JSONGrapher_record(clean_for_plotly=False) #We use the False argument here because the cleaning will be on the next line with beyond default arguments.
|
1107
|
+
self.fig_dict = clean_json_fig_dict(self.fig_dict, fields_to_update=['simulate', 'custom_units_chevrons', 'equation', 'trace_style', '3d_axes', 'bubble', 'superscripts'])
|
1097
1108
|
fig = pio.from_json(json.dumps(self.fig_dict))
|
1098
1109
|
#restore the original fig_dict.
|
1099
1110
|
self.fig_dict = original_fig_dict
|
@@ -1390,8 +1401,8 @@ class JSONGrapherRecord:
|
|
1390
1401
|
#Make some pointers to external functions, for convenience, so people can use syntax like record.function_name() if desired.
|
1391
1402
|
def validate_JSONGrapher_record(self):
|
1392
1403
|
validate_JSONGrapher_record(self)
|
1393
|
-
def update_and_validate_JSONGrapher_record(self):
|
1394
|
-
update_and_validate_JSONGrapher_record(self)
|
1404
|
+
def update_and_validate_JSONGrapher_record(self, clean_for_plotly=True):
|
1405
|
+
update_and_validate_JSONGrapher_record(self, clean_for_plotly=clean_for_plotly)
|
1395
1406
|
|
1396
1407
|
|
1397
1408
|
# helper function to validate x axis and y axis labels.
|
@@ -2928,24 +2939,61 @@ def get_fig_dict_ranges(fig_dict, skip_equations=False, skip_simulations=False):
|
|
2928
2939
|
|
2929
2940
|
### Start section of code with functions for cleaning fig_dicts for plotly compatibility ###
|
2930
2941
|
|
2931
|
-
def update_title_field(
|
2942
|
+
def update_title_field(fig_dict_or_subdict, depth=1, max_depth=10):
|
2932
2943
|
""" This function is intended to make JSONGrapher .json files compatible with the newer plotly recommended title field formatting
|
2933
2944
|
which is necessary to do things like change the font, and also necessary for being able to convert a JSONGrapher json_dict to python plotly figure objects.
|
2934
2945
|
Recursively checks for 'title' fields and converts them to dictionary format. """
|
2935
|
-
if depth > max_depth or not isinstance(
|
2936
|
-
return
|
2946
|
+
if depth > max_depth or not isinstance(fig_dict_or_subdict, dict):
|
2947
|
+
return fig_dict_or_subdict
|
2937
2948
|
|
2938
|
-
for key, value in
|
2939
|
-
if key == "title" and isinstance(value, str):
|
2940
|
-
|
2949
|
+
for key, value in fig_dict_or_subdict.items():
|
2950
|
+
if key == "title" and isinstance(value, str): #This is for axes labels.
|
2951
|
+
fig_dict_or_subdict[key] = {"text": value}
|
2941
2952
|
elif isinstance(value, dict): # Nested dictionary
|
2942
|
-
|
2953
|
+
fig_dict_or_subdict[key] = update_title_field(value, depth + 1, max_depth)
|
2943
2954
|
elif isinstance(value, list): # Lists can contain nested dictionaries
|
2944
|
-
|
2945
|
-
return
|
2955
|
+
fig_dict_or_subdict[key] = [update_title_field(item, depth + 1, max_depth) if isinstance(item, dict) else item for item in value]
|
2956
|
+
return fig_dict_or_subdict
|
2957
|
+
|
2946
2958
|
|
2947
2959
|
|
2948
2960
|
|
2961
|
+
def update_superscripts_strings(fig_dict_or_subdict, depth=1, max_depth=10):
|
2962
|
+
""" This function is intended to make JSONGrapher .json files compatible with the newer plotly recommended title field formatting
|
2963
|
+
which is necessary to do things like change the font, and also necessary for being able to convert a JSONGrapher json_dict to python plotly figure objects.
|
2964
|
+
Recursively checks for 'title' fields and converts them to dictionary format. """
|
2965
|
+
if depth > max_depth or not isinstance(fig_dict_or_subdict, dict):
|
2966
|
+
return fig_dict_or_subdict
|
2967
|
+
|
2968
|
+
for key, value in fig_dict_or_subdict.items():
|
2969
|
+
if key == "title": #This is for axes labels and graph title.
|
2970
|
+
if "text" in fig_dict_or_subdict[key]:
|
2971
|
+
fig_dict_or_subdict[key]["text"] = replace_superscripts(fig_dict_or_subdict[key]["text"])
|
2972
|
+
if key == "data": #This is for the legend.
|
2973
|
+
for data_dict in fig_dict_or_subdict[key]:
|
2974
|
+
if "name" in data_dict:
|
2975
|
+
data_dict["name"] = replace_superscripts(data_dict["name"])
|
2976
|
+
elif isinstance(value, dict): # Nested dictionary
|
2977
|
+
fig_dict_or_subdict[key] = update_superscripts_strings(value, depth + 1, max_depth)
|
2978
|
+
elif isinstance(value, list): # Lists can contain nested dictionaries
|
2979
|
+
fig_dict_or_subdict[key] = [update_superscripts_strings(item, depth + 1, max_depth) if isinstance(item, dict) else item for item in value]
|
2980
|
+
return fig_dict_or_subdict
|
2981
|
+
|
2982
|
+
#The below function was made with the help of copilot.
|
2983
|
+
def replace_superscripts(input_string):
|
2984
|
+
#Example usage: print(replace_superscripts("x^(2) + y**(-3) = z^(test)"))
|
2985
|
+
import re
|
2986
|
+
# Step 1: Wrap superscript expressions in <sup> tags
|
2987
|
+
output_string = re.sub(r'\^\((.*?)\)|\*\*\((.*?)\)',
|
2988
|
+
lambda m: f"<sup>{m.group(1) or m.group(2)}</sup>",
|
2989
|
+
input_string)
|
2990
|
+
# Step 2: Remove parentheses if the content is only digits
|
2991
|
+
output_string = re.sub(r'<sup>\((\d+)\)</sup>', r'<sup>\1</sup>', output_string)
|
2992
|
+
# Step 3: Remove parentheses if the content is a negative number (- followed by digits)
|
2993
|
+
# Step 4: Remove parentheses if the superscript is a single letter
|
2994
|
+
output_string = re.sub(r'<sup>\((\w)\)</sup>', r'<sup>\1</sup>', output_string)
|
2995
|
+
output_string = re.sub(r'<sup>\(-(\d+)\)</sup>', r'<sup>-\1</sup>', output_string)
|
2996
|
+
return output_string
|
2949
2997
|
|
2950
2998
|
|
2951
2999
|
def convert_to_3d_layout(layout):
|
@@ -3089,6 +3137,7 @@ def clean_json_fig_dict(json_fig_dict, fields_to_update=None):
|
|
3089
3137
|
because one would not want to do that by mistake before simulation is performed.
|
3090
3138
|
This function can also remove the 'equation' field from data series. However, that is not the default behavior
|
3091
3139
|
because one would not want to do that by mistake before the equation is evaluated.
|
3140
|
+
The "superscripts" option is not normally used until right before plotting because that will affect unit conversions.
|
3092
3141
|
"""
|
3093
3142
|
if fields_to_update is None: # should not initialize mutable objects in arguments line, so doing here.
|
3094
3143
|
fields_to_update = ["title_field", "extraInformation", "nested_comments"]
|
@@ -3112,6 +3161,8 @@ def clean_json_fig_dict(json_fig_dict, fields_to_update=None):
|
|
3112
3161
|
fig_dict = remove_trace_style_field(fig_dict)
|
3113
3162
|
if "3d_axes" in fields_to_update: #This is for 3D plots
|
3114
3163
|
fig_dict = update_3d_axes(fig_dict)
|
3164
|
+
if "superscripts" in fields_to_update:
|
3165
|
+
fig_dict = update_superscripts_strings(fig_dict)
|
3115
3166
|
|
3116
3167
|
return fig_dict
|
3117
3168
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: jsongrapher
|
3
|
-
Version: 3.
|
3
|
+
Version: 3.9
|
4
4
|
Summary: The python version of JSONGrapher with tools for creating JSONGrapher Records.
|
5
5
|
Home-page: https://github.com/AdityaSavara/jsongrapher-py
|
6
6
|
Author: Aditya Savara
|
7
|
-
Author-email:
|
7
|
+
Author-email: AdityaSavara2008@u.northwestern.edu
|
8
8
|
License: BSD-3-Clause
|
9
9
|
Classifier: License :: OSI Approved :: BSD License
|
10
10
|
Classifier: Programming Language :: Python
|
@@ -1,4 +1,4 @@
|
|
1
|
-
JSONGrapher/JSONRecordCreator.py,sha256=
|
1
|
+
JSONGrapher/JSONRecordCreator.py,sha256=nENtRcr0hlysqhRIc-BhYRE8VN9Q8TaB0IC74jiKUzw,209780
|
2
2
|
JSONGrapher/UnitPytesting.py,sha256=xizJ-2fg9C5oNMFJyfavbBLMusayE9KWQiYIRrQQd4A,4363
|
3
3
|
JSONGrapher/UnitpyCustomUnitsTesting.py,sha256=Rwq5p8HXN0FP54lRFgLTV0kgJ9TpcFaD3_C0MEOoEzw,1297
|
4
4
|
JSONGrapher/__init__.py,sha256=cc5qXQidP_ABPXdnXy_DTdgPanHuR7ya45LV-BdWVh8,277
|
@@ -9,10 +9,10 @@ JSONGrapher/units_list.py,sha256=ROrlAsD66oPozZmOaE65xjNUEg3CxkSmA8iPE2_ihYI,344
|
|
9
9
|
JSONGrapher/styles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
JSONGrapher/styles/layout_styles_library.py,sha256=vGb1tE_ETY-Blj2frt8ddHA976ADFSCoabjzKn2ZNYU,3051
|
11
11
|
JSONGrapher/styles/trace_styles_collection_library.py,sha256=DUbbO8jTlhn2q-lOY1XYGkHV1RbJX-P5Z1SUCM0qo6M,5952
|
12
|
-
jsongrapher-3.
|
13
|
-
jsongrapher-3.
|
14
|
-
jsongrapher-3.
|
15
|
-
jsongrapher-3.
|
16
|
-
jsongrapher-3.
|
17
|
-
jsongrapher-3.
|
18
|
-
jsongrapher-3.
|
12
|
+
jsongrapher-3.9.data/data/LICENSE,sha256=MroL1bQKoAHrMJv2KvABMmZX5j-DZ2EP_zaQacLUtj0,1465
|
13
|
+
jsongrapher-3.9.data/data/README.md,sha256=OntfAICB_uwfjoq8tMDYc_W7eXSC2N22X0udPIGb2Nw,5888
|
14
|
+
jsongrapher-3.9.dist-info/LICENSE,sha256=MroL1bQKoAHrMJv2KvABMmZX5j-DZ2EP_zaQacLUtj0,1465
|
15
|
+
jsongrapher-3.9.dist-info/METADATA,sha256=q1LGWAVZNTTawUuuWZzy8WypNwQv7tdYWNIt1xWSbsE,6960
|
16
|
+
jsongrapher-3.9.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
17
|
+
jsongrapher-3.9.dist-info/top_level.txt,sha256=5f7Ui2hCKCPTQOjD540WKghKNYOvUDNfdpnDbIlAD3Y,12
|
18
|
+
jsongrapher-3.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|