Last modified: 7 November 2025

Tricks to accessing the plot data [New]


The data used to create the plot, contour, and error analysis visualizations can be retrieved with the corresponding get_xxx_plot, get_xxx_contour, or get_xxx_proj calls. There are two issues when making these calls:

  1. When do I need to set the recalc argument?
  2. Why does the data change if I create a new visualization?

There is also the need to access the actual data from these objects.


When do I need to set the recalc argument?

If you have just created the visualization then you can call the get_xxx call with no arguments, which means using the recalc=False argument. This does mean that you get the data from the last call to the routine, so it should only be done when you know what that call was.

Setting recalc=True should be used:

  • if you do not want to create the actual visualization, and you just want the data needed to create it,

  • or you are not sure what data was used for the last call.

When recalc=True you will need to send in the same data that would be used in the visualation call. For example:

pdata = get_reg_proj(src.kt, src.abundanc, id=2, nloop=(21, 21), recalc=True)

However, this can take some time to run.


Why does the data change if I create a new visualization?

The following code will not create the data for the two data plots:

plot_data(1)
pdata1 = get_data_plot()
plot_data(2, overplot=True)
pdata2 = get_data_plot()

This is because the get_xxx calls return a reference to the relevant plot objects, rather than a copy. This means that the pdata1 and pdata2 objects contain the same data.

The Python copy module provides an easy way to copy the objects, which lets you say

import copy

plot_data(1)
pdata1 = copy.deepcopy(get_data_plot())
plot_data(2, overplot=True)
pdata2 = copy.deepcopy(get_data_plot())

or, if you do not want to create the visualizations:

pdata1 = copy.deepcopy(get_data_plot(recalc=True))
pdata2 = copy.deepcopy(get_data_plot(2, recalc=True))

Accessing the actual data

The plot objects have a number of attributes that can be used to create your own visualization. The actual attributes depend on what the "type" is - e.g. is it from get_data_plot, get_fit_plot, get_model_contour, or get_reg_proj - and the type of the data (1D, integrated 1D, 2D, or an image). The simplest way to find out what is available is to print out the object.

For example, for a PHA dataset, get_data_plot will return (taken from the plotting a PHA dataset example):

sherpa> pdata = get_data_plot()
sherpa> print(pdata)
xlo    = [0.292 ,0.3212,0.3504,0.3796,0.4088,0.438 ,0.4526,0.4672,0.4818,0.4964,
 0.511 ,0.5256,0.5402,0.5548,0.5694,0.584 ,0.5986,0.6132,0.6278,0.6424,
 0.657 ,0.6716,0.6862,0.7008,0.7154,0.73  ,0.7446,0.7592,0.7738,0.7884,
 0.803 ,0.8176,0.8322,0.8468,0.8614,0.876 ,0.8906,0.9052,0.9198,0.9344,
 0.949 ,0.9636,0.9782,0.9928,1.0074,1.022 ,1.0366,1.0512,1.0658,1.0804,
 1.095 ,1.1096,1.1242,1.1388,1.1534,1.168 ,1.1826,1.1972,1.2118,1.2264,
 1.241 ,1.2556,1.2702,1.2848,1.2994,1.314 ,1.3432,1.3578,1.3724,1.387 ,
 1.4016,1.4162,1.4308,1.4454,1.46  ,1.4746,1.4892,1.5038,1.5184,1.533 ,
 1.5622,1.5914,1.606 ,1.6352,1.6644,1.6936,1.7082,1.7374,1.752 ,1.7812,
 1.8104,1.825 ,1.8396,1.8688,1.898 ,1.9272,1.9418,1.9856,2.0148,2.044 ,
 2.0732,2.1024,2.1462,2.2046,2.2484,2.3068,2.3506,2.3944,2.4674,2.5258,
 2.5696,2.628 ,2.6718,2.7156,2.7448,2.8032,2.8616,2.92  ,2.993 ,3.0514,
 3.1098,3.1974,3.285 ,3.358 ,3.431 ,3.5186,3.6062,3.7084,3.869 ,3.942 ,
 4.0442,4.161 ,4.2632,4.3654,4.4968,4.5844,4.745 ,4.9494,5.1538,5.3582,
 5.7378,5.9568,6.5554]
xhi    = [0.3212,0.3504,0.3796,0.4088,0.438 ,0.4526,0.4672,0.4818,0.4964,0.511 ,
 0.5256,0.5402,0.5548,0.5694,0.584 ,0.5986,0.6132,0.6278,0.6424,0.657 ,
 0.6716,0.6862,0.7008,0.7154,0.73  ,0.7446,0.7592,0.7738,0.7884,0.803 ,
 0.8176,0.8322,0.8468,0.8614,0.876 ,0.8906,0.9052,0.9198,0.9344,0.949 ,
 0.9636,0.9782,0.9928,1.0074,1.022 ,1.0366,1.0512,1.0658,1.0804,1.095 ,
 1.1096,1.1242,1.1388,1.1534,1.168 ,1.1826,1.1972,1.2118,1.2264,1.241 ,
 1.2556,1.2702,1.2848,1.2994,1.314 ,1.3432,1.3578,1.3724,1.387 ,1.4016,
 1.4162,1.4308,1.4454,1.46  ,1.4746,1.4892,1.5038,1.5184,1.533 ,1.5622,
 1.5914,1.606 ,1.6352,1.6644,1.6936,1.7082,1.7374,1.752 ,1.7812,1.8104,
 1.825 ,1.8396,1.8688,1.898 ,1.9272,1.9418,1.9856,2.0148,2.044 ,2.0732,
 2.1024,2.1462,2.2046,2.2484,2.3068,2.3506,2.3944,2.4674,2.5258,2.5696,
 2.628 ,2.6718,2.7156,2.7448,2.8032,2.8616,2.92  ,2.993 ,3.0514,3.1098,
 3.1974,3.285 ,3.358 ,3.431 ,3.5186,3.6062,3.7084,3.869 ,3.942 ,4.0442,
 4.161 ,4.2632,4.3654,4.4968,4.5844,4.745 ,4.9494,5.1538,5.3582,5.7378,
 5.9568,6.5554,7.008 ]
y      = [0.01  ,0.0123,0.0091,0.0173,0.0182,0.0182,0.0219,0.0246,0.031 ,0.0319,
 0.031 ,0.0355,0.0337,0.031 ,0.0301,0.0319,0.0365,0.0374,0.0374,0.0328,
 0.0365,0.0419,0.0401,0.0337,0.0319,0.0355,0.0374,0.0401,0.0383,0.0374,
 0.0365,0.0355,0.0474,0.0438,0.0319,0.0392,0.0346,0.0328,0.0438,0.0474,
 0.0337,0.0428,0.0246,0.0365,0.0273,0.0392,0.0383,0.0328,0.041 ,0.0337,
 0.0301,0.0447,0.0355,0.0292,0.0355,0.0328,0.0273,0.0283,0.0246,0.0255,
 0.0264,0.0255,0.0319,0.0246,0.0255,0.0228,0.0237,0.0201,0.0264,0.0301,
 0.0191,0.0191,0.0182,0.0219,0.0255,0.0237,0.0273,0.0182,0.0273,0.0169,
 0.0141,0.0255,0.0146,0.0182,0.015 ,0.0201,0.0132,0.0191,0.0109,0.0173,
 0.0191,0.0191,0.0132,0.0137,0.0141,0.0182,0.0106,0.01  ,0.0164,0.0096,
 0.0096,0.0064,0.0057,0.0076,0.0055,0.0073,0.0061,0.0046,0.005 ,0.0061,
 0.0062,0.0061,0.0064,0.0096,0.0046,0.0064,0.0059,0.0044,0.0057,0.0046,
 0.0033,0.0033,0.0036,0.0038,0.0038,0.003 ,0.0026,0.0019,0.0036,0.0026,
 0.0023,0.0029,0.0026,0.0021,0.003 ,0.0017,0.0014,0.0014,0.0014,0.0007,
 0.0012,0.0004,0.0005]
xlabel = Energy (keV)
ylabel = Counts/sec/keV
title  = 9774.pi
histo_prefs = {'xlog': False, 'ylog': False, 'label': None, 'xerrorbars': False, 'yerrorbars': True, 'color': None, 'linestyle': 'None', 'linewidth': None, 'marker': '.', 'alpha': None, 'markerfacecolor': None, 'markersize': None, 'ecolor': None, 'capsize': None}

However, not that the print display does not include all possible attributes. In this case we have (dropping the "internal" attributes that start with an underscore):

sherpa> print([n for n in dir(pdata) if not n.startswith("_")])
['histo_prefs', 'hline', 'overplot', 'plot', 'prepare', 'title', 'vline', 'x', 'xerr', 'xhi', 'xlabel', 'xlo', 'y', 'yerr', 'ylabel']

so, even though this is for a 1D histogram dataset (that is, there are xlo and xhi fields), there is also the x attribute, giving the mid-point of these, and possible errors for each axis. This can then be used - e.g. to create your own visualization using matplotlib:

import matplotlib.pyplot as plt
plt.errorbar(pdata.x, pdata.y, yerr=pdata.yerr, ecolor="gray", elinewidth=0.5)
plt.xscale("log")
plt.yscale("log")
plt.xlabel(pdata.xlabel)
plt.ylabel(pdata.ylabel)

Figure 1: manually displaying a PHA dataset

[The data points are connected by a blue lnie and each has an error bar indicated by a thin gray line. The axes are drawn with a logarithmic scale and labelled "Energy (keV)" and "Counts/sec/kev" for X and Y axes, respectively.]
[Print media version: The data points are connected by a blue lnie and each has an error bar indicated by a thin gray line. The axes are drawn with a logarithmic scale and labelled "Energy (keV)" and "Counts/sec/kev" for X and Y axes, respectively.]

Figure 1: manually displaying a PHA dataset