Select to view content in your preferred language

Can the Temporal Profile chart on the Multidimensional toolbar be scripted?

292
8
09-09-2024 09:15 AM
DougBrowning
MVP Esteemed Contributor

I built out a couple Multidimensional Multivariate Rasters and then use the Multidimensional toolbar to make Temporal Profiles super fast and it is pretty slick.

Temporal Profile Multiple Variables.gif

I now want to be able get a temporal profile in script for a given polygon to add to our reporting tool.  So basically simulate the above gif and get back a SVG of the chart that I add to our larger PDF.

I am not finding a way in script.  Is this possible?

I found the arcpy.raster one

temporal_profile(points=[], time_field=None, variables=[], bands=[0], time_extent=None, dimension=None, dimension_values=[], show_values=False, trend_type=None, trend_order=None, plot_properties={})

But it is not giving me anything and not sure how points fits in.  I got a chart to display just giving it time but its blank.

Thanks a lot

0 Kudos
8 Replies
DougBrowning
MVP Esteemed Contributor

In addition if I try to just use the charting from arcpy none of the code in the help makes much sense.

https://pro.arcgis.com/en/pro-app/latest/arcpy/charts/line.htm 

Like here chart is not defined anywhere?

import arcpy

aprx = arcpy.mp.ArcGISProject('current')
censusLayer = aprx.listMaps()[0].listLayers('Census Block Groups')[0]

# Set data source of chart object to a layer within current project
chart.dataSource = censusLayer

# Save the chart to file with dimensions width=500, height=500
chart.exportToSVG('populationByState.svg', 500, 500)

There is a arcpy.charts.line and arcpy.Chart that seem to intermingle some parts of the code samples?

Then I tried the info from this article  https://www.esri.com/arcgis-blog/products/arcgis-pro/analytics/using-arcgis-notebooks-and-arcpy-char...

myChart = arcpy.Chart("test")
myChart.type = 'line'
myChart.dataSource = mdRaster

myChart.exportToSVG(r"C:\temp\Charts\test.svg", 500, 500)

And I just get RuntimeError: Invalid dataset: on my crf.

Honestly I have been trying these charts for years but this is when I usually give up and just use Seaborn or some other package like that. 

Appreciate any links to something that can work for a Multidimensional raster and get me a temporal profile.  Maybe @ChristopherAllen ?

Its so easy in Pro I just need to automate it.  

thanks

ChristopherAllen
Esri Contributor

Hi @DougBrowning ,

Thanks for the feedback regarding charts documentation/code samples. The blog post you referenced was created before the new charts module (https://pro.arcgis.com/en/pro-app/latest/arcpy/charts/what-is-the-charts-module.htm) was introduced, and it will be updated to reflect the new API. We'll also look into making the code samples in the documentation clearer.

Thanks again

HongXu
by Esri Contributor
Esri Contributor

The temporal profile itself does not have its own chart type, it basically gets a time/value array from the multidimensional raster and draw a line chart. To obtain that time/value array, you can run Sample tool, which takes point or polygon as input, and create an output table which can be used in creating a line chart.

DougBrowning
MVP Esteemed Contributor

I ended up using Zonal stats as table since I get so much more info.   Then load that into a panda then seaborn to chart it.  It was literally two lines of code for a single var.  But splitting all 9 variables in my raster out then combing back into one chart is a bit of a pain in code.  

Access to the temporal profile tool would be much easier to chart all the vars and I like the way it handles the labels better and the chart points.  Please consider opening it up.  Thanks

0 Kudos
DougBrowning
MVP Esteemed Contributor

I tested the Sample tool and I like the output there better actually and it can feed directly into a panda all in memory.  Thanks for that idea!  (I thought the service did not work but it was parallelProcessingFactor="100%" that was causing it to fail - not sure why.

I built a CRF out for climate data yesterday and that Temporal Profile tool is a home run.  Just so fast to process so much data.  It may be worth its own toolbox.

Seems to work with a CRF directly or a service.  Pretty fast.

 

 

 

# first use the sample tool to pull out the means for a given polygon. setting extent seems to help speed a lot
with arcpy.EnvManager(parallelProcessingFactor="100%", extent=polygonAOI):
arcpy.sa.Sample(
in_rasters=rcmapCRF,
in_location_data=polygonAOI,
out_table=os.path.join("memory", "tempTable"),
resampling_type="NEAREST",
process_as_multidimensional="ALL_SLICES",
acquisition_definition=None,
statistics_type="MEAN",
percentile_value=None,
buffer_distance=None,
layout="ROW_WISE",
generate_feature_class="TABLE"
)

#Convert NumPy array to pandas DataFrame.
fc_np = arcpy.da.FeatureClassToNumPyArray(os.path.join("memory", "tempTable"), "*") 

df = pd.DataFrame(fc_np)

 

 

 

I was able to use arcpy charting to get one line chart but was not figuring out how to stack multiple vars in one chart.

It does not seem like I can give it more than one var for x and if I stack them like plot works I just get 1 line.  There must be a way since the Temporal Profile tool can do it but I cannot find any samples.  It is way easier to avg by year.  How do I chart multiple vars from a CRF?

chart = arcpy.charts.Line(x='StdTime', y='AvgTempC', aggregation="mean", timeIntervalSize=1, timeIntervalUnits='YEARS')
chart = arcpy.charts.Line(x='StdTime', y='AvgPrecipitationMM', aggregation="mean", timeIntervalSize=1, timeIntervalUnits='YEARS')
 

So I just went with mathplotlib.

f, ax = plt.subplots(1, 1)
ax.plot(df["StdTime"], df["AnnualHerbaceous"], color="blue", label="Annual Herbaceous", linestyle="-", marker='.')
 
Thanks a lot
0 Kudos
ChristopherAllen
Esri Contributor

Hi @DougBrowning ,

If I understand correctly, you want to create a single chart displaying one line for each of your variables. To do this you would pass the `y` argument a list of all your field names. Using your example, this would be:

 

chart = arcpy.charts.Line(x='StdTime', y=['AvgTempC', 'AvgPrecipitationMM'], aggregation="mean", timeIntervalSize=1, timeIntervalUnits='YEARS')

 

Hope this helps!

Chris

DougBrowning
MVP Esteemed Contributor

Yep that works.  I figured that would be the way but the help says string.  I should have tested just busy.  Sorry about that.

ChristopherAllen
Esri Contributor

Awesome, glad to hear that worked. Thank you for following up.