madscatt / zazzie

development branch
GNU General Public License v3.0
2 stars 3 forks source link

Determine how Plotly handles out of range data #181

Open skrueger111 opened 1 month ago

skrueger111 commented 1 month ago

Determine how Plotly handles a data point that is out of range. Related to #180, specific to match point plot. However, we want to determine how to handle out of range data in a general way for all modules.
1) If a fit fails and there are no valid calculated values for the parameters, how do we test for this? In this case, we likely would want to output an error message instead of a plot. 2) If a point to be plotted is way out of range of the rest of the data, how can we control the scale of the plot? Axes are currently set to autoscaling by default. 3) What about data plotted on a log scale? Plotly.js does not directly provide an equivalent for handling non-positive values on a logarithmic scale like Matplotlib’s nonpositive='clip' option. Non-positive values on a logarithmic axis are set to a very large negative number. This causes issues when plotting SAS data, as there are often some negative values at high q. Also, even if the values at high q are positive, the error bars are often large and can reach negative values. As in 2) above, how can we best control the scale of the plot?

skrueger111 commented 1 week ago

For log scale plots, I found that:

HTML file to set a range for the log y axis (taken from data interpolation):

<!DOCTYPE html>
<html>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<body>

    <div id="myDiv" style="height:100%;max-height:700px;width:100%"></div>

<script>

var trace1 = {
    x: [0.0, 0.02, 0.04, 0.06, 0.08, 0.1, 0.12000000000000001, 0.14, 0.16, 0.18, 0.19999999999999998, 0.21999999999999997, 0.23999999999999996, 0.25999999999999995, 0.27999999999999997, 0.3],
    y: [0.04, 0.03466709389085204, 0.021822257463758498, 0.012356043503275084, 0.00771460329088166, 0.004927556885294044, 0.003175217658413404, 0.00228076267707953, 0.0013816115786250032, 0.0016322554197651692, 0.0008935166957219779, 0.0008260618316226525, 0.0005887499235681783, 0.0003995834563528376, -0.00012845425888767347, 0.00019761645874579692],
    error_y: {
        type: 'data',
        array: [0.001, 0.0017767511185624596, 0.0008619388432011342, 0.0007512384571108444, 0.0005243655752119969, 0.0004358446704927374, 0.00042880051739416024, 0.0004046779676815942, 0.0003732532364708736, 0.00038278127866323404, 0.00034113369622010964, 0.0003392000918113071, 0.0004013516199967173, 0.0003861689808285628, 0.0004180230871286464, 0.0004529034161480606],
        visible: true,
        thickness: 1.5,
        width: 0, //to remove the end caps
    },
    type: 'scatter',
    mode: 'lines+markers',
    name: 'interpolated data',
    marker: {color: 'blue', size: '6', symbol: 'circle',},
    line: {
        color: 'blue',
        dash: 'solid',
        width: '2', shape: 'spline',
    }, 
    hoverinfo: 'x+y',
};

var trace2 = {
    x: [0.0, 0.01298, 0.01402, 0.01506, 0.0161, 0.01713, 0.01817, 0.01921, 0.02025, 0.02129, 0.02233, 0.02336, 0.0244, 0.02544, 0.02648, 0.02752, 0.02855, 0.02959, 0.03063, 0.03167, 0.0327, 0.03374, 0.03478, 0.03582, 0.03685, 0.03789, 0.03893, 0.03997, 0.041, 0.04204, 0.04308, 0.04377, 0.04411, 0.04515, 0.04619, 0.04722, 0.04757, 0.04826, 0.0493, 0.05033, 0.05137, 0.05241, 0.05344, 0.05448, 0.05517, 0.05551, 0.05655, 0.05758, 0.05862, 0.05896, 0.05966, 0.06069, 0.06173, 0.06276, 0.0638, 0.06483, 0.06587, 0.06655, 0.0669, 0.06793, 0.06897, 0.07, 0.07035, 0.07104, 0.07414, 0.07793, 0.08171, 0.0855, 0.08928, 0.09306, 0.09684, 0.1006, 0.1044, 0.1082, 0.1119, 0.1157, 0.1195, 0.1232, 0.127, 0.1307, 0.1345, 0.1382, 0.142, 0.1457, 0.1494, 0.1532, 0.1569, 0.1606, 0.1644, 0.1681, 0.1718, 0.1755, 0.1792, 0.1829, 0.1866, 0.1903, 0.194, 0.1977, 0.2013, 0.205, 0.2087, 0.2124, 0.216, 0.2197, 0.2233, 0.227, 0.2306, 0.2342, 0.2379, 0.2415, 0.2451, 0.2487, 0.2523, 0.2559, 0.2595, 0.2631, 0.2667, 0.2703, 0.2738, 0.2774, 0.2809, 0.2845, 0.288, 0.2916, 0.2951, 0.2986, 0.3021, 0.3057, 0.3092, 0.3127, 0.3162, 0.3196, 0.3231, 0.3266, 0.3301, 0.3335, 0.337, 0.3404, 0.3438, 0.3473, 0.3507, 0.3541, 0.3575, 0.3609, 0.3643, 0.3677, 0.371, 0.3744, 0.3778, 0.3811, 0.3845, 0.3878, 0.3911, 0.3945, 0.3978],
    y: [0.04, 0.03428, 0.03437, 0.03493, 0.03348, 0.03478, 0.03424, 0.03443, 0.03472, 0.03454, 0.03341, 0.03394, 0.03306, 0.03242, 0.03123, 0.03128, 0.02938, 0.02857, 0.02964, 0.02854, 0.02753, 0.02731, 0.02539, 0.02594, 0.02395, 0.02437, 0.02417, 0.02188, 0.02126, 0.02223, 0.02017, 0.02051, 0.0204, 0.01965, 0.01769, 0.01787, 0.01849, 0.01823, 0.01816, 0.01792, 0.0157, 0.01563, 0.01618, 0.01406, 0.0147, 0.015, 0.01323, 0.01366, 0.01297, 0.0132, 0.01282, 0.01159, 0.01181, 0.01187, 0.01089, 0.01019, 0.0112, 0.01033, 0.009101, 0.01092, 0.009119, 0.009996, 0.008494, 0.009416, 0.007915, 0.007934, 0.007072, 0.006332, 0.006009, 0.005793, 0.005412, 0.004808, 0.003892, 0.003437, 0.004185, 0.003708, 0.003106, 0.003666, 0.002365, 0.002644, 0.00223, 0.002313, 0.00214, 0.001877, 0.001915, 0.002457, 0.002089, 0.001341, 0.001733, 0.001357, 0.001577, 0.000697, 0.00182, 0.0003537, 0.001284, 0.0008943, 0.0008433, 0.0006045, 0.001081, 0.001029, 0.0005793, 0.0004285, 0.0007124, 0.0007901, 0.001299, 0.0007922, 0.000277, 0.0003989, 0.0002732, 0.0006949, 0.000257, 0.001113, 0.0003168, 0.0006184, 0.0003892, 0.0007489, 0.0007801, 0.0007301, 0.000953, 0.0004409, -0.0001566, 0.0006263, 0.0003845, -0.0002441, 0.000507, 0.0003009, 0.0001805, 0.0003545, 0.0006034, 0.0004188, -0.0007518, 0.0004534, 0.001365, 0.0002595, -6.49e-05, -0.0004745, 0.0007445, -0.000188, -0.000186, -8.277e-05, 0.0002717, -0.0001859, -7.799e-05, 0.000139, 0.0001494, 0.0001197, 0.0003784, 9.857e-05, 0.0002228, -0.0001657, -0.0005047, 0.0006767, -0.0009159, -0.0003672, 0.0006086],
    error_y: {
        type: 'data',
        array: [0.001, 0.002675, 0.002528, 0.002162, 0.002092, 0.001897, 0.001772, 0.001739, 0.001755, 0.001519, 0.001597, 0.001412, 0.001356, 0.001207, 0.001179, 0.001184, 0.001315, 0.001149, 0.001105, 0.001136, 0.0009803, 0.001075, 0.001093, 0.0009965, 0.0009398, 0.0008917, 0.0008787, 0.0008622, 0.0008575, 0.0008846, 0.0008511, 0.0006003, 0.0008616, 0.0008006, 0.0008611, 0.0007688, 0.0006148, 0.0007841, 0.0008101, 0.0007946, 0.0005548, 0.000736, 0.0007404, 0.0007988, 0.0005304, 0.0006914, 0.000685, 0.0007326, 0.0007453, 0.0005349, 0.0006986, 0.0006962, 0.0007576, 0.0007119, 0.0007302, 0.000745, 0.0007627, 0.0004804, 0.0008094, 0.0007902, 0.0008835, 0.0008703, 0.0004491, 0.0009332, 0.0004775, 0.0004467, 0.0004678, 0.0004624, 0.0004538, 0.0004841, 0.0004459, 0.0004372, 0.0004558, 0.0004723, 0.0004483, 0.0004561, 0.0004363, 0.0003835, 0.0004055, 0.0004131, 0.0003825, 0.0004131, 0.0003958, 0.0004246, 0.0003821, 0.0004311, 0.0004078, 0.0003697, 0.0003805, 0.0004084, 0.0003688, 0.0003466, 0.0003771, 0.000381, 0.0003434, 0.0003594, 0.0003427, 0.0003442, 0.0003426, 0.0003628, 0.0003479, 0.0003575, 0.0003462, 0.0003388, 0.0003464, 0.000338, 0.0003341, 0.0003735, 0.0004099, 0.0003996, 0.00043, 0.0003919, 0.0004172, 0.0004191, 0.0003868, 0.0004022, 0.0004191, 0.0004416, 0.0004207, 0.0004543, 0.0004086, 0.0004373, 0.0004335, 0.0004556, 0.0004455, 0.0004434, 0.0004581, 0.0004221, 0.0004397, 0.0004014, 0.0004335, 0.0004539, 0.0004512, 0.0004191, 0.0004859, 0.0004704, 0.0004601, 0.0004427, 0.0004524, 0.0004289, 0.0004778, 0.0004491, 0.0004047, 0.000505, 0.0004367, 0.0004542, 0.0004226, 0.000434, 0.0004763, 0.000546, 0.0005898, 0.0005826, 0.0006051, 0.0007623, 0.0008],
        visible: true,
        thickness: 1.5,
        width: 0, //to remove the end caps
    },
    type: 'scatter',
    mode: 'markers',
    name: 'original data',
    marker: {color: 'red', size: '4.5', symbol: 'circle',},
    hoverinfo: 'x+y',
};

// add the signal cutoff point to the plot
var trace3 = {
    x: [0.1792],
    y: [0.00182],
    error_y: {
        type: 'data',
        array: [0.02],
        visible: true,
        thickness: 2.5,
        width: 0, //to remove the end caps
    },
    type: 'scatter',
    mode: 'lines+markers',
    name: 'cutoff q value = 0.1792<br>[I(q)/(std.dev. I(q))] < 2',
    line: {color: 'grey', dash: 'solid', width: 3},
    marker: {color: 'grey', size: '2', symbol: 'circle',},
    hoverinfo: 'x+y',
};

var data = [trace2, trace1, trace3];

var layout = {
    title: {
        text:'data interpolation plot',
        y: 0.9, 
        x: 0.47, 
    },
    hovermode: 'x',
    xaxis: {
        title: 'q (Å<sup>-1</sup>)',
        type: 'log',
        autorange: true,
        showgrid: true,
        zeroline: false,
        showline: true,
        autotick: true,
        ticks: 'inside',
        mirror: 'ticks',
        showticklabels: true,
//        hoverformat: '.2r',
  },
    yaxis: {
        title: 'I(q)',
        type: 'log',
//        autorange: true, //this seems to override all other settings; set to false or omit if you want to set the range
//        range: [-4, -1], // to set the y-axis range (take log in this case); if both values aren't set, the plot will autoscale the entire range
        range: [-3.74, -1.36],
// NOTE:  autorangeoptions.clipmin: -4 didn't work, minallowed: -4 didn't work
//NOTE:  I thought about a range slider, but you can only have one for the x axis
        showgrid: true,
        zeroline: false,
        showline: true,
        autotick: true,
        ticks: 'inside',
        mirror: 'ticks',
        showticklabels: true,
        exponentformat: 'e',
  },
};

var config = {
    responsive: true,
    scrollZoom: true,
// plot the image with its default values, but double the size
    toImageButtonOptions: {
        format: 'png', // one of png, svg, jpeg, webp
//        filename: 'custom_image',
//        height: 500,
//        width: 700,
        scale: 2, // Multiply title/legend/axis/canvas sizes by this factor
    },
    modeBarButtonsToRemove: ['select2d','lasso2d'],    
// the following two lines allow the user to edit the plot in the browser and save the changes to their plotly account
    showLink: true,
    plotlyServerURL: "https://chart-studio.plotly.com",
};

Plotly.newPlot('myDiv', data, layout, config);

//Plotly.newPlot('myDiv', data, layout, {responsive: true, scrollZoom: true});

</script>
</body>
</html>