Hi All,
Is there any way set the default numeric formatting s in Arcpy for pro?
I am using ArcPro 2.4.0
I have a number of layers in a map that I am preparing for sharing into Portal and we wish to format the number of decimal places and enable/disable the thousands separators
I am using .LRYX files to style the features and this is set in the layer file e.g.:
{
"type" : "CIMFieldDescription",
"alias" : "SVCurr",
"fieldName" : "AllData_SVCurr",
"numberFormat" : {
"type" : "CIMNumericFormat",
"alignmentOption" : "esriAlignRight",
"alignmentWidth" : 0,
"roundingOption" : "esriRoundNumberOfDecimals",
"roundingValue" : 0,
"useSeparator" : true
},
but it does not seem to be reading the layer file for this setting ( I am running Apply Symbology from Layer)
https://pro.arcgis.com/en/pro-app/tool-reference/data-management/alter-field-properties.htm does not seem to have these options
Thanks in advance.
Solved! Go to Solution.
Worked out how to do this using the Cartographic Information Model (https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/python-cim-access.htm) :
------------------------------------------------------------------------------------------------------------
#List of Fields to Format with comma delimiters
SpCommaDelimFields=["AllData_Ld","AllData_P", "AllData_SR"]
#List of Fields to Format with 2 decimal places
SpTwoDecFields=["AllData_Ld","AllData_P", "AllData_SR"]
currentProject = arcpy.mp.ArcGISProject("CURRENT")
currentMap = currentProject.listMaps()[0] #I think this assumes there is only one map
layers = currentMap.listLayers()
for layer in layers:
lyrCIM = layer.getDefinition('V2')
if layer.name == "TheLayer":
lyrCIM.showPopups = True # show popups
lyrCIM.expanded = True # At least one of these seems to help the map refresh
# Modify the display of numeric fields
for fd in lyrCIM.featureTable.fieldDescriptions:
fdNumFmt = fd.numberFormat
if fd.fieldName in SpCommaDelimFields:
fdNumFmt.useSeparator = True #Use a comma as a thousands separator
if fd.fieldName in SpTwoDecFields:
fdNumFmt.roundingValue = 2 #Two decimal places
-------------------------------------------------------------------------------------------------------------------
# Push the changes back to the layer object
layer.setDefinition(lyrCIM)
#Get the layer definition again to check that it has changed
lyrCIMNew = layer.getDefinition('V2')
messages.addMessage( layer.name + " showPopups after: " + str(lyrCIMNew.showPopups))
messages.addMessage( layer.name + " showMapTips after: " + str(lyrCIMNew.showMapTips))
currentProject.save
Note that this is ArcPro 2.4 - the portion of the lyrx file that handles the format looks like this:
{
"type" : "CIMFieldDescription",
"alias" : "Ld",
"fieldName" : "AllData_Ld",
"numberFormat" : {
"type" : "CIMNumericFormat",
"alignmentOption" : "esriAlignRight",
"alignmentWidth" : 0,
"roundingOption" : "esriRoundNumberOfDecimals",
"roundingValue" : 2,
"useSeparator" : true
},
It's a good idea to export the Lyrx file and check the Json to see if it matches this example or check out the specification https://github.com/esri/cim-spec
EDIT: in 2.8 I use a script to check the Layer file directly - see below
delete this..
I haven't tried, but "roundingValue" : 0,
suggests to me to not use any rounding... what if you change it to 2 or 3? does it have any affect?
Changing it to 2 in the layer file is possible, then you get 2 decimal places, e.g.
{
"type" : "CIMFieldDescription",
"alias" : "Ld",
"fieldName" : "AllData_Ld",
"numberFormat" : {
"type" : "CIMNumericFormat",
"alignmentOption" : "esriAlignRight",
"alignmentWidth" : 0,
"roundingOption" : "esriRoundNumberOfDecimals",
"roundingValue" : 2,
"useSeparator" : true
},
The layerx file is saved with the correct number of decimal places if you alter the data in Fields View manually as well but then using Apply Symbology from Layer to apply those formatting settings doesn't work. The data is back at 6 decimal places so I'm looking for a way to make the changes in the Python script.
The only way to change the number formatting seems to be via Fields View - select each field, alter manually.... Not an ideal workflow when preparing multiple maps a week to upload to Portal for our users.
We are generating the tables via a join to excel spreadsheets and there doesn't seem to be a way to alter the number formats when we do the join either.
Even if we could modify the default formatting in Pro from 6 decimal places, no comma it would help.
Leandra... long been a complaint that the column formatting from spreadsheets isn't retained.
I tend to use numpy arrays, or you can try *.csv format. If you format the columns in the spreadsheet then the number of decimals is retained in the output. Attached is a file that contained an id column and two originally identical columns. The first was free-range formatted and the second with 4 decimal places to show. With ExcelToTable, everything was displayed to 6 decimal places and there was no numeric truncation. With the csv, the output truncated to the display width
A0,B1,C3
1,1.012345679,1.0123
2,1.012345678,1.0123
3,1.01234567,1.0123
4,1.0123456,1.0123
5,1.012345,1.0123
6,1.01234,1.0123
9,1.0123,1.0123
I'm thinking now that the only way to address issues like this is to export the data as layer files, hack into the layer files and then redraw the whole map. e.g. https://community.esri.com/t5/python-questions/turn-off-fields-with-python/td-p/403316
I really don't know why ESRI has such limited functionality in arcpy.
The limitation is how to deal with excel. csv is a far safer format since there are no surprises
Unfortunately that means actually rounding the data itself, which means that any calculations we want to do in pro will be inaccurate. What I need is the data to be stored with x decimals but display to users as a rounded value. It's not really a solution I'm afraid.
Worked out how to do this using the Cartographic Information Model (https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/python-cim-access.htm) :
------------------------------------------------------------------------------------------------------------
#List of Fields to Format with comma delimiters
SpCommaDelimFields=["AllData_Ld","AllData_P", "AllData_SR"]
#List of Fields to Format with 2 decimal places
SpTwoDecFields=["AllData_Ld","AllData_P", "AllData_SR"]
currentProject = arcpy.mp.ArcGISProject("CURRENT")
currentMap = currentProject.listMaps()[0] #I think this assumes there is only one map
layers = currentMap.listLayers()
for layer in layers:
lyrCIM = layer.getDefinition('V2')
if layer.name == "TheLayer":
lyrCIM.showPopups = True # show popups
lyrCIM.expanded = True # At least one of these seems to help the map refresh
# Modify the display of numeric fields
for fd in lyrCIM.featureTable.fieldDescriptions:
fdNumFmt = fd.numberFormat
if fd.fieldName in SpCommaDelimFields:
fdNumFmt.useSeparator = True #Use a comma as a thousands separator
if fd.fieldName in SpTwoDecFields:
fdNumFmt.roundingValue = 2 #Two decimal places
-------------------------------------------------------------------------------------------------------------------
# Push the changes back to the layer object
layer.setDefinition(lyrCIM)
#Get the layer definition again to check that it has changed
lyrCIMNew = layer.getDefinition('V2')
messages.addMessage( layer.name + " showPopups after: " + str(lyrCIMNew.showPopups))
messages.addMessage( layer.name + " showMapTips after: " + str(lyrCIMNew.showMapTips))
currentProject.save
Note that this is ArcPro 2.4 - the portion of the lyrx file that handles the format looks like this:
{
"type" : "CIMFieldDescription",
"alias" : "Ld",
"fieldName" : "AllData_Ld",
"numberFormat" : {
"type" : "CIMNumericFormat",
"alignmentOption" : "esriAlignRight",
"alignmentWidth" : 0,
"roundingOption" : "esriRoundNumberOfDecimals",
"roundingValue" : 2,
"useSeparator" : true
},
It's a good idea to export the Lyrx file and check the Json to see if it matches this example or check out the specification https://github.com/esri/cim-spec
EDIT: in 2.8 I use a script to check the Layer file directly - see below
Edit - Actually the code runs fine, but for whatever reason the change to the layer CIM isn't saved when I use
layer.setDefinition(lyrCIM) the changes aren't written back in 2.8.1 BUT I have also added lyrCIM.expanded = True to a few of the layers and ??maybe?? that forces a map refresh
I'm using Pro v. 2.8 and I don't see anything related to the Number Format menu in the exported *.lyrx file? I am trying to do the same thing as you, which is to have a faster way to set the decimal place to 0 and check the Show thousands separators box.