Set Multiple Scale Ranges with Document Properties

Working with multiple scales in Spotfire visualizations can be a bit of a pain. I frequently find I have more scales than I need, and getting them synched up to the same min and max values can be frustrating. Last week, I built a project that allowed users to set multiple scale ranges with document properties. Not only does it give users more control, but it keeps multiple scales synched. It required a little bit of IronPython but was easy to setup. Read on to learn how.

Blog or Video?

I know many people prefer watching a video to reading a long post, so I am trying to do more with my YouTube channel. You can find all the content from this post in the video embedded below or thru this direct link to YouTube. I try to keep all videos to less than 10 minutes for Otherwise, just scroll down.

My Visualization

Here is the visualization I was working with. As you can see, I have four columns on my y-axis. I really want one scale on each side, but all of the options available to me for multiple scales lead to four scales (second screenshot below).

If I can’t get down to two scales, the scales on each side must have the same min and max. Otherwise, the chart is too hard to read. Every time the data updates, the scale range needs to change. Going into the properties dialog to adjust it is far too inefficient. I knew I could set the scale range with document properties and IronPython. I just needed a bit of code to get started.

Even if I setup the chart with 2 color, I still get 4 scales.

Starting Code

Sayali Patel posted a TIBCO Community article on this subject that served as an excellent starting place. Her code did require a few modifications though. I wanted users to be able to update the ranges, rather than have them hardcoded. And, I also wanted to set the range for four scales.

# Copyright © 2017. TIBCO Software Inc. Licensed under TIBCO BSD-style license.

#Let's assume there are 2 columns "Sum([Col1]), Sum([Col2])" on the y-axis of a line chart. Color is set to (Column Names). The multiple scales for 
#each color is turned on. Notice that there is a possibility to set different scale ranges using the drop down in the individual scale settings 
#part of the property page. The naming of the two axes there are the same as the display name of the expressions on the axis (in this case Sum(Col1) and Sum(Col2)).

from Spotfire.Dxp.Application.Visuals import LineChart
from Spotfire.Dxp.Application.Visuals import AxisRange

#To set the axis range:
lChart = lineChart.As[LineChart]()
newAxisRange = AxisRange(-2000, 60000)
lChart.YAxis.IndexedRange["Sum(Col1)"] = newAxisRange

#To read the manually set axis range:


print lChart.YAxis.IndexedRange["Sum(Col1)"].Low
print lChart.YAxis.IndexedRange["Sum(Col2)"].High

My Modifications

So, I created two document properties called PurpleScale and RedScale. They are input property controls using a Real data type.

Then, I modified the code as follows:

  1. Added a reference to the Document Properties in lines 6 and 24. Now the code will read the values in my Document Properties.
  2. Copied and pasted the code in line 7 into line 8 and entered in the names of my columns.
  3. Copied and pasted the print code to print the low and high values for each of my columns. This step is entirely optional. It just provides visual confirmation.
  4. Repeated steps 1 -3 for the second scale.
  5. Create a parameter to hook up the code to the visualization.
  6. Run the script.

Here is the final result of my page. To change the scale, all the user has to do is update the property controls and click Update Scale.

This code is also easy to modify for other visualization types. I used the exact same code on a combination plot. All I had to do was swap out all references to LineChart for ComboChart. Use this handy reference to find the right API for your visualization. Now you know how to use IronPython to set multiple scale ranges with document properties.

Code Snippet for Copy Paste

from Spotfire.Dxp.Application.Visuals import LineChart
from Spotfire.Dxp.Application.Visuals import AxisRange

#To set the axis range:
lChart = lineChart.As[LineChart]()
newAxisRange = AxisRange(0, Document.Properties["PurpleScale"])
lChart.YAxis.IndexedRange["planned cost"] = newAxisRange
lChart.YAxis.IndexedRange["actual cost"] = newAxisRange

#To read the manually set axis range:
print lChart.YAxis.IndexedRange["planned cost"].Low
print lChart.YAxis.IndexedRange["planned cost"].High
print lChart.YAxis.IndexedRange["actual cost"].Low
print lChart.YAxis.IndexedRange["actual cost"].High

from Spotfire.Dxp.Application.Visuals import LineChart
from Spotfire.Dxp.Application.Visuals import AxisRange

#To set the axis range:
lChart = lineChart.As[LineChart]()
newAxisRange = AxisRange(0, Document.Properties["RedScale"])
lChart.YAxis.IndexedRange["cum planned cost"] = newAxisRange
lChart.YAxis.IndexedRange["cum actual cost"] = newAxisRange

#To read the manually set axis range:
print lChart.YAxis.IndexedRange["cum actual cost"].Low
print lChart.YAxis.IndexedRange["cum actual cost"].High
print lChart.YAxis.IndexedRange["cum planned cost"].Low
print lChart.YAxis.IndexedRange["cum planned cost"].High

Spotfire Version

Content created with Spotfire 10.2.

Other Posts on IronPython

8 thoughts on “Set Multiple Scale Ranges with Document Properties”

  1. Hi Julie,

    Love your blog! Definitely the best way for oil and gas professionals to improve spotfire skills.

    Unrelated to this post-have you covered using Spotfire to correctly pivot on API10? I have noticed a few errors(i.e. the later completion dates not consistently in order). I have tried column sort of API14 but does not seem to stay in that order when I Pivot to API10. If you have covered this please link. Thanks!

    1. Hi Kate, thanks for commenting. Spotfire reads rows into the application based on the order of records in the database. If you are working with an information link, you can add order by clauses that will sort the data as it is coming in. That’s the order it will stay in throughout the analysis. I have worked on this problem before, and I created a step in my process that showed where API10 had duplicate records (API14 would have been different wells). Then, the user had to choose which one they wanted. Hope that helps.

    2. The sort function is really only applicable to a table visualization and doesn’t impact any of your transformation processes and won’t “hold” as you noted. The sort with the order by clause will “hold”.

  2. Hi, do you have any idea why my code is not working for my combination chart?
    I get this error:
    Traceback (most recent call last):
    File “”, line 5, in
    AttributeError: ‘type’ object has no attribute ‘As’

    from Spotfire.Dxp.Application.Visuals import CombinationChart
    from Spotfire.Dxp.Application.Visuals import AxisRange

    #To set the axis range:
    lChart = CombinationChart.As[CombinationChart]()
    newAxisRange = AxisRange(0, Document.Properties[“Revenue”])
    lChart.YAxis.IndexedRange[“Gross_RevOil”] = newAxisRange
    lChart.YAxis.IndexedRange[“Gross_RevCond”] = newAxisRange
    lChart.YAxis.IndexedRange[“Gross_RevGas”] = newAxisRange
    lChart.YAxis.IndexedRange[“Gross_RevLiquids”] = newAxisRange

    #To read the manually set axis range:
    print lChart.YAxis.IndexedRange[“Gross_RevOil”].Low
    print lChart.YAxis.IndexedRange[“Gross_RevOil”].High
    print lChart.YAxis.IndexedRange[“Gross_RevCond”].Low
    print lChart.YAxis.IndexedRange[“Gross_RevCond”].High
    print lChart.YAxis.IndexedRange[“Gross_RevGas”].Low
    print lChart.YAxis.IndexedRange[“Gross_RevGas”].High
    print lChart.YAxis.IndexedRange[“Gross_RevLiquids”].Low
    print lChart.YAxis.IndexedRange[“Gross_RevLiquids”].High

  3. Hi, can you explain what the code in line 5 means? lChart = lineChart.As[LineChart]()

    I tried replacing LineChart to CombinationChart and it is not working.

    1. lChart and lineChart are objects.
      LineChart is the API reference.
      Here is the code I used for my combination chart.
      #To set the axis range:
      cChart = combinationChart.As[CombinationChart]()
      newAxisRange = AxisRange(0, Document.Properties[“GreenScaleS2”])
      cChart.YAxis.IndexedRange[“avg stages per day”] = newAxisRange
      cChart.YAxis.IndexedRange[“actual stages per day”] = newAxisRange
      cChart.YAxis.IndexedRange[“planned stages per day”] = newAxisRange

  4. The error was due to the script parameter name not matching the code in line 5. Thank you for this great tutorial!

Leave a Reply

Your email address will not be published. Required fields are marked *