POST
|
Michael, Unfortunately I never found a better solution than switching to Pro. The script was developed for a suite of desktop-based geoprocessing tools for users interested in resource sustainability. The only "compromise" I came up with was articulating in the user guide for these geoprocessing tools that ArcGIS may need to be restarted after running the tool. Not an ideal solution at all, but it was all I could do.
... View more
09-13-2018
01:23 PM
|
0
|
0
|
1324
|
POST
|
Thanks Dan, I appreciate your suggestion. I do have import sys at the beginning of my script (sorry for not initially including my code). The script is fairly long, but I'm including the primary parts of it here: #Import modules
import os
import pandas as pd
import numpy as np
import pygal as pg
import sys
import arcpy
arcpy.env.overwriteOutput = True
arcpy.env.outputCoordinateSystem = arcpy.SpatialReference(3857)
def plotFAO(df, iso_code, fao_indicator, itemCodeFS, countrySelection, outputLocation):
arcpy.AddMessage("IN FAO LOOP")
#Select the appropriate indicator
df_selected = df[df["Item Code"] == itemCodeFS]
#color code for plots
customColorStyle = pg.style.Style(colors = ['#D35400', '#979A9A', '#797D7F', '#5F6A6A', '#515A5A'], title_font_size = 18)
arcpy.AddMessage("added Style")
if itemCodeFS == 21010:
#Creat the line chart plot
line_chart = pg.Line(title = u"Average Dietary Energy Supply Adequacy - \n" + countrySelection, x_title = "End Year of '3-Year Average'", y_title = "% - 3-Year Average", style = customColorStyle, show_dots = False, stroke_style = {'width': 3}, show_minor_y_labels = True)
line_chart.x_labels = map(str, range(2001, 2018))
#Get just the Value column for the country of interest and the country groupings
country_series = df_selected.loc[df_selected["ISO_code"] == iso_code, "Value"]
low_income_series = df_selected.loc[df_selected["ISO_code"] == "lowestIncome", "Value"]
mid_lower_income_series = df_selected.loc[df_selected["ISO_code"] == "midLowerIncome", "Value"]
mid_upper_income_series = df_selected.loc[df_selected["ISO_code"] == "midUpperIncome", "Value"]
high_income_series = df_selected.loc[df_selected["ISO_code"] == "uppermostIncome", "Value"]
#Add Pd Series to the line chart
line_chart.add(countrySelection, country_series)
line_chart.add("Low-Income", low_income_series)
line_chart.add("Lower-Middle-Income", mid_lower_income_series)
line_chart.add("Upper-Middle-Income", mid_upper_income_series)
line_chart.add("High-Income", high_income_series)
#Output the plot
line_chart.render_to_file(os.path.join(outputLocation, 'test_pygal3.svg'))
def foodSecurity_v1():
#FAO Data
fao_clean = "C:\\Users\\Paul McCord\\Google Drive\\Toolbox\\Tool_First\\FoodSecurity\\Content_Post052418\\Data_Tabular\\FAOSTAT\\fao_clean.csv"
#Country ISO codes
country_iso_csv = "C:\\Users\\Paul McCord\\Google Drive\\Toolbox\\Tool_First\\FoodSecurity\\Content_Post052418\\Data_Tabular\\country_codes\\FAO_Area_Export.csv"
#Set tool parameters
#Local variables
out_src_FeatureSet = r"in_memory\src_feature_set"
#User specified parameters
src_FeatureSet = arcpy.GetParameterAsText(0)
countrySelection = arcpy.GetParameterAsText(1)
fao_indicator = arcpy.GetParameterAsText(2)
outputLocation = arcpy.GetParameterAsText(3)
try:
#Save the Feature Set to Feature Layer
arcpy.MakeFeatureLayer_management(src_FeatureSet, out_src_FeatureSet)
aoi = arcpy.CopyFeatures_management(out_src_FeatureSet, os.path.join(arcpy.env.scratchFolder, "AOI_layer.shp"))
#Obtain the country ISO code to avoid formatting problems with country name
df_iso = pd.read_csv(country_iso_csv)
countryDF = df_iso[df_iso["Area"] == countrySelection]
iso_code = countryDF["ISO_code"].iloc[0]
arcpy.AddMessage("country: " + countrySelection + ", code: " + iso_code)
arcpy.AddMessage(iso_code)
#Obtain the Item Code and Item Description selected by the user
if fao_indicator == "Average dietary energy supply adequacy (%) (3-year average)":
itemCodeFS = 21010
if fao_indicator == "Average value of food production (constant I$ per person) (3-year average)":
itemCodeFS = 21011
if fao_indicator == "Share of dietary energy supply derived from cereals, roots and tubers (%) (3-year average)":
itemCodeFS = 21012
if fao_indicator == "Average protein supply (g/capita/day) (3-year average)":
itemCodeFS = 21013
if fao_indicator == "Average supply of protein of animal origin (g/capita/day) (3-year average)":
itemCodeFS = 21014
if fao_indicator == "Rail-lines density (per 100 square km of land area)":
itemCodeFS = 21016
if fao_indicator == "Gross domestic product per capita, PPP (constant 2011 international $)":
itemCodeFS = 22013
if fao_indicator == "Prevalence of undernourishment (%) (3-year average)":
itemCodeFS = 21004
if fao_indicator == "Depth of the food deficit (kcal/capita/day) (3-year average)":
itemCodeFS = 21023
#Select FAO Food Security information of interest
df = pd.read_csv(fao_clean, dtype = {"Area": "S100", "Area Code": "f8", "Element": "S25", "Element Code": "f8", "Flag": "S25",
"Flag Description": "S25", "ISO_code": "S25", "Item": "S150", "Item Code": "i4", "Unit": "S25",
"Value": "f8", "Year": "S25", "Year Code": "f8", "YearEnd": "i4"})
plotFAO(df, iso_code, fao_indicator, itemCodeFS, countrySelection, outputLocation)
#test output layer
arcpy.SetParameter(4, aoi)
#arcpy.SetParameter(4, fig)
#except Exception:
# e = sys.exc_info()[1]
# arcpy.AddError('An error occurred: {}'.format(e.args[0]))
except Exception:
if exc_info is not None and exec_info is not (None, None, None):
e = sys.exc_info()[1]
arcpy.AddError('An error occurred: {}'.format(e.args[0]))
if __name__ == '__main__':
foodSecurity_v1() There are actually nine food security indicators that I'm plotting, but I've only included the code for the first indicator in the 'plotFAO' function. The other plotting snippets look nearly identical, just with different food security indicators. I've tried a couple of options in the 'except' statement, but none have been successful. Thanks again for weighing in.
... View more
06-15-2018
05:35 PM
|
0
|
1
|
4364
|
POST
|
I am developing a script tool that will be part of a suite of tools in an ArcToolbox. This script tool is intended to plot FAO food security indicators. When I run this tool the first time from ArcToolbox (ie, I run the tool from ArcMap), it successfully completes without an issue (ie, the Pygal module (which I import) plots the food security indicator that the user selects for the country selected by the user). However, the second time that I run the tool, it fails with the following error: Traceback (most recent call last): File "C:\Users\Paul McCord\Google Drive\Toolbox\Tool_First\FoodSecurity\Content_Post052418\TestScripts\foodSecurity_v1.py", line 5, in <module> import pygal as pg File "C:\Python27\ArcGIS10.5\lib\site-packages\pygal\__init__.py", line 28, in <module> import pkg_resources File "C:\Python27\ArcGIS10.5\lib\site-packages\pkg_resources\__init__.py", line 46, in <module> from pkg_resources.extern import six File "C:\Python27\ArcGIS10.5\lib\site-packages\pkg_resources\extern\__init__.py", line 43, in load_module mod = sys.modules[extant] AttributeError: 'NoneType' object has no attribute 'modules' Referring to a separate post that suggested removing the 'Try-Except' statement, I've tried removing this in order to resolve the issue, but it persists. A similar GeoNet post exists (https://community.esri.com/thread/44095 ); however, in this post, the issue appears to arise from 'ImportToolbox.' I believe my issue arises from a module that I'm importing. Nevertheless, it does not appear that the issue was resolved in the earlier post. Does anyone have experience with this issue while developing a Python script for a script tool? Thanks, Paul
... View more
06-15-2018
09:52 AM
|
0
|
17
|
8102
|
POST
|
Thank you Dan, Unfortunately, I need to include this as a script tool belonging to a larger suite of script tools that are shipped in an Arc Toolbox, so the users won't have the option to run as a standalone script. Since there seems to be this conflict between the applications, I might see if another library is able to plot my data without the conflict. Thank you, Paul
... View more
06-13-2018
01:09 PM
|
0
|
1
|
556
|
POST
|
I have a Python script that I'm using in a script tool in ArcToolbox. This script reads FAO food security indicator data and then plots the data for a country that the user chooses. When I run the script outside of ArcGIS, it plots the data with no issues. However, when the script tool is run within ArcGIS, I receive an error the second time it is run. The error is: "An error occurred: expected string or buffer" The first time the script tool runs, everything works fine: it outputs a figure with food security information. It's the second time I run the tool that it fails and returns the above error. A similar question was asked here: Arc Toolbox Python script tool plot legend error And ultimately the solution that was arrived at was to restart ArcGIS. When I restart ArcGIS, I am able to successfully run the tool again, but, as expected, it fails on the subsequent run. This will be inconvenient for the users of this tool since I don't want them to have to restart ArcGIS every time they run the tool for a different country or different food security indicator. I've identified in the script where the issue occurs. I've imported matplotlib.pyplot as plt, and when my script includes 'plt.legend' in order to add a legend to the figure, this is what causes the script to fail on the second run. If I remove plt.legend from the script, I can run the tool as many times in succession as I want without an error (unfortunately, the plots that are created no longer have a legend). Has anyone encountered this issue in the past? If so, have you found a way to overcome this without restarting ArcGIS every time? Here's my code where I add the legend: plt.figure(figsize = (12, 9)) ax = plt.subplot(111) ax.get_xaxis().tick_bottom() ax.get_yaxis().tick_left() ax.tick_params(axis = "both", labelsize = 10) lineDrawType = [(5, 2, 20, 2), (2, 5), (4, 4, 2, 2), (4, 10), (5, 2)] obsList = [iso_code, "lowestIncome", "midLowerIncome", "midUpperIncome", "uppermostIncome"] labelObsNames = [countryName, "Low-Income", "Lower-Middle-Income", "Upper-Middle-Income", "High-Income"] for rank, locationName in enumerate(obsList): df_plot = df_selected[df_selected["ISO_code"] == locationName] plt.plot(df_plot["YearEnd"], df_plot["Value"], lw = 3., color = tableau[rank], ls = "--", dashes = lineDrawType[rank], label = labelObsNames[rank]) artList = [] lgdPlotter = plt.legend(loc = "upper center", bbox_to_anchor = (0.5, -0.1), ncol=3) artList.append(lgdPlotter) plt.savefig(os.path.join(outputLocation, "test2.png"), additional_artists = artList, bbox_inches = "tight") plt.close("all")
... View more
06-13-2018
07:57 AM
|
0
|
3
|
659
|
POST
|
I have a mosaic dataset that contains global rasters. Each of these rasters contains information on the number of people within a pixel by age group as well as sex. For example, one raster captures the number of males aged 0-4, while another contains the number of males aged 5-9, and so on in four year increments. This information is provided for the years 2000, 2010, 2015, and 2020. The mosaic dataset therefore contains many large raster datasets (430 to be exact). I'm new to mosaic datasets so I'm partly trying to understand if what I'd like to do is appropriate for a mosaic dataset. What I'm attempting to do is to query the dataset by both location and time. For example, I'd like to query by the extent of Brazil for the year 2000. I'd then like to use the result of this query to iterate through all of the four year age block rasters. So in this case, I would be iterating through rasters representing 0-4 year old males in Brazil for the year 2000, then 5-9 year old males in Brazil for the year 2000, and so forth. On each iteration, I would perform some basic calculations, like summing up the total number of people aged 0-4, then summing up the total number of people aged 5-9, and so forth. I'm familiar with the Select by Attributes and Select by Location tools, but with my limited knowledge of mosaic datasets, I'm not convinced that once I've selected my area of interest and year of interest, I'll be able to perform calculations on just the rasters that have been selected. I'm considering using the "Export Mosaic Dataset Items" to export only the selected rasters and then perform my analysis on these individual rasters, but I'm hesitant to do this given the sheer number of rasters that I have. Any advice pertaining to how I could effectively query my mosaic dataset to work with individual rasters within it, or, if this isn't appropriate for a mosaic dataset, other techniques for doing this (like using the "Export Mosaic Dataset Items tool) would be much appreciated. Thank you, Paul
... View more
08-22-2017
12:33 PM
|
0
|
0
|
627
|
POST
|
Apologies, as you suggested, I've now run the Create Referenced Mosaic Dataset tool using the Kenya polygon to set the Extent from Dataset, and it works perfectly. Thanks for your help! Paul
... View more
08-16-2017
11:50 AM
|
0
|
0
|
3635
|
POST
|
Thanks Mody! I think I'm now on the right track, but I'm getting a strange output when I edit the boundaries. I took your advice and copy and pasted my mosaic data set to a new mosaic and then edited the boundary of the new mosaic by right clicking on the mosaic data set in the Catalog panel, then choosing Modify, then choosing Import Footprints or Boundary. I filled out the tool as shown below, making sure that the Target Feature Class was set to Boundary: However, my output was the following: It might be hard to see, but there's a Boundary around Kenya as I was hoping to get (in purple just right of center), but as you can see there's nothing to view now. When I select the value of pixels both within and outside of the Boundary, I get a pixel value of -1. I imagine there's a simple explanation or a simple step that I'm missing here. Thanks again, Paul
... View more
08-16-2017
07:55 AM
|
0
|
0
|
3635
|
POST
|
Hello, I've created a mosaic data set that contains population information at five time points for the African continent (2000, 2005, 2010, 2015, 2020). There is one raster for each time point (ie, 2000 population, 2005 population, etc.). So there are a total of five rasters in the mosaic data set. Because these rasters are large, my goal is to clip the mosaic data set by an area of interest (AOI) defined by a polygon and produce a mosaic data set that includes the rasters for the five time points but clipped by the AOI. I would then do my analysis using this AOI mosaic data set. However, when I use the Clip (Data Management) tool, I'm returned only a single raster data set with two values: 0 and a large number that depends on the area that I've clipped. Below is how I filled out the Clip tool: The Input Raster field is filled out with the path to the mosaic data set and the the Output Extent is a path leading to a shapefile for the area of interest (in this case, Kenya). But, as I mentioned above, the output is a single raster data set of Kenya with only two values, 0 and 134582. I'm curious if part of the problem I'm having is due to the fact that all of my rasters within the mosaic data set overlap completely? In other words, the raster for African population in the year 2000 overlaps perfectly with the raster for African population in the year 2005, and so on. Is there a way to run the Clip tool - or any other tool for that matter - on a time series mosaic data set, like the one I have here, and have it return a time series mosaic data set that has been clipped by the AOI? Thank you for your help. Paul
... View more
08-15-2017
02:14 PM
|
0
|
3
|
5490
|
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:24 AM
|