I want to fill a line graph in javafx using for loop. At every iteration it should plot the line as per the value in array of integers.
You will already have found the solution. But here you go (I assume you have a List<Integer[]> arrayList):
//Defining X axis
NumberAxis xAxis = new NumberAxis();
//Defining y axis
NumberAxis yAxis = new NumberAxis();
//Make LineChart
LineChart linechart = new LineChart(xAxis, yAxis);
//Make List to save your XYChartSeries
List<XYChart.Series> seriesList = new ArrayList<>();
//Iterate over your Data
for (Integer[] integers : arrayList) {
XYChart.Series series = new XYChart.Series();
for (int i = 0; i < integers.length; i++) {
Integer integer = integers[i];
series.getData().add(new XYChart.Data(i, integer));
}
seriesList.add(series);
linechart.getData().add(seriesList.get(seriesList.size() - 1));
}
Related
I'm a new ILNumerics Visualization Engine user and I'm still coming up to speed on how to use it well. I've searched extensively for how to update the z-values of an ILSurface and read the posts, but I'm still not clear on how to do this.
I'm able to generate a surface and set up a camera to view it (Hamyo Kutschbach told me that's the best way to ensure that the aspect ratios of the surface don't change when rotating the surface, which is important in my application). Here's the code that displays a sin(x)/x function:
// Generate the data
ILArray<double> z = SincFunc(rows, cols, 10, 50);
ILArray<double> x = new double[cols];
ILArray<double> y = new double[rows];
for (int i = 0; i < cols; i++)
x[i] = (double)i;
for (int i = 0; i < rows; i++)
y[i] = (double)i;
// create the scene
scene = new ILScene();
pointCloudSurface = new ILSurface(z, x, y)
{
Colormap = Colormaps.Jet,
UseLighting = true,
Wireframe = { Visible = false },
Children = { new ILColorbar()
{
Height = 0.5f,
Location = new PointF(0.95f, 0.05f),
Children = { new ILLabel("microns") { Position = new Vector3(0.5,1,0), Anchor = new PointF(0.5f,0) } } }
},
Alpha = 1.0f
};
// Configure the surface and display it
scene.Camera.Add(pointCloudSurface);
scene.Camera.Position = new Vector3(50, 50, 700);
scene.Camera.LookAt = new Vector3(50, 50, 0);
scene.Camera.Top = new Vector3(0, 0, 700);
scene.Camera.Projection = Projection.Perspective;
scene.Camera.ZNear = 1.0f;
scene.Camera.ZFar = 0.0f;
scene.Camera.Top = new Vector3(1, 0, 0);
// Turn off the Powered by ILNumerics label
scene.Screen.First<ILLabel>().Visible = false;
ilPanel1.Scene = scene;
ilPanel1.Configure();
ilPanel1.Refresh();
And it works well. So now I want to change the z-values and update the plot without closing ilPanel1 because this plot is embedded in a Windows Form. Advice would be appreciated! Hopefully other newbies will find this post useful as well.
After further rummaging around, I came across a method, UpdateColormapped(), that does the trick. It's placed near the end of the code above like this:
scene.Camera.First<ILSurface>().UpdateColormapped(z);
ilPanel1.Scene = scene;
ilPanel1.Configure();
ilPanel1.Refresh();
It can be found in the API documentation here: UpdateColormapped()
It can also change the x and y data and perform other mods, but it requires that the z data be a float array, so if you're working double precision, you'll have to take the appropriate steps to get it into a float array.
Is there a way to manipulate the range of Z values for a Surface plot in a way that can preserve the original values so I can create a range slider with a min and max values from the GetLimits() method and then update the data array Z values so I can set new limits but move the slides back and forth to adjust the min/max Z value and see the plot adjust as I do it?
Given this code
ILArray<float> tempArray = ILMath.tosingle(myDoubleArray);
dataArray.a = tempArray;
var plotCube = ilPanel1.Scene.First<ILPlotCube>();
var surface = plotCube.First<ILFastSurface>();
surface.Update(Z: dataArray, colormap: new ILColormap(ILColormaps.ILNumerics));
ilPanel1.Refresh();
The MinValue and MaxValue controls are initialized like this.
float maxZ, minZ;
dataArray.GetLimits(out minZ, out maxZ);
var zRange = maxZ - minZ;
MinValue.Maximum = (decimal)maxZ;
MinValue.Minimum = (decimal)minZ;
MinValue.Value = (decimal)minZ;
MaxValue.Maximum = (decimal)maxZ;
MaxValue.Minimum = (decimal)minZ;
MaxValue.Value = (decimal)maxZ;
I want to be able to manipulate the Z values in the array like this
dataArray[dataArray < (float)MinValue.Value] = (float)MinValue.Value;
dataArray[dataArray > (float)MaxValue.Value] = (float)MaxValue.Value;
var plotCube = ilPanel1.Scene.First<ILPlotCube>();
var surface = plotCube.First<ILFastSurface>();
surface.Update(Z: dataArray, colormap: new ILColormap(ILColormaps.ILNumerics));
ilPanel1.Refresh();
The issue is that dataArray is being changed with new min/max values. How can I restore dataArray if you want to change back to a larger min/max? Do I just clone dataArray and use that to change the plot? Or is there a feature of ILArray that tracks changes and can restore the array?
The solution to this problem is to use a temporary array and clone the original array and then normalize the temporary array and update the surface with it.
float min = surface.GetRangeMinValue(AxisNames.CAxis) + minOffs;
float max = surface.GetRangeMaxValue(AxisNames.CAxis) + maxOffs;
ILArray<float> tempArray = _dataArray.C;
tempArray[tempArray < min] = min;
tempArray[tempArray > max] = max;
surface.Update(Z: tempArray);
_dataArray is a static property loaded once with the original data. Any updates are done with the code above
I have three 2D-arrays that all have same X and Y coordinates but different values.
Each of these arrays represent a temperature of a room in certain height (eg. array1 = 10m, array2 = 5m, array3= 3m).
I have created a ILPlotCube that has three different ILContourPlots for these arrays but all of them get positioned to same Z-axis spot of cube (0):
this.scene = new ILScene();
ILPlotCube pc = new ILPlotCube(twoDMode: false);
ILArray<float> TA = tempRoom.GetILArray("TA");
ILContourPlot cpa = new ILContourPlot(TA, create3D: false);
ILArray<float> TB = tempRoom.GetILArray("TB");
ILContourPlot cpb = new ILContourPlot(TB, create3D: false);
ILArray<float> TC = tempRoom.GetILArray("TC");
ILContourPlot cpc = new ILContourPlot(TC, create3D: false);
pc.Add(cpa);
pc.Add(cpb);
pc.Add(cpc);
scene.Add(pc);
ilPanel1.Scene = this.scene;
ilPanel1.Refresh();
Image of result: http://i.stack.imgur.com/VNLgB.jpg
How can I set manually range of the Z-axis of cube shown in picture and manually set Z-axis-position of each ILContourPlot without messing up contours in ILContourPlots?
Contour plots in ILNumerics are regular scene graph objects - just like evey other plot. You can transform them in arbitray ways using regular group objects:
ILArray<float> A = ILMath.tosingle(ILSpecialData.terrain);
ilPanel1.Scene.Add(new ILPlotCube(twoDMode: false) {
new ILGroup(translate: new Vector3(0,0,10)) {
new ILContourPlot(A["0:50;0:50"])
},
new ILGroup(translate: new Vector3(0,0,5)) {
new ILContourPlot(A["50:100;50:100"],lineWidth: 3)
},
new ILGroup(translate: new Vector3(0,0,3)) {
new ILContourPlot(A["150:200;150:200"])
}
});
Gives:
But if you use it in a 2D setup it gets confusing quickly. Obviously you have to use the configuration options for lines and contour levels in order to distinguish individual contour plots. Or use a 3D view.
I’m having 2 problems with a simple XYSeries line graph.
When the absolute value of the difference between the last plotted point and the next plotted point is less than 11 the label on the next plotted point goes missing. I want all the labels to display.
I have some (not all) missing vertical grid lines and don’t see why. I want a vertical grid line for every XY coordinate.
Thanks for the help. Here's the code.
String glucoseLegendText = getString(R.string.glucose_legend_text);
XYSeries series = new XYSeries(glucoseLegendText);
datasource = new HistoryDataSource(this);
datasource.open();
Cursor c = datasource.getQuery();
c.moveToFirst();
int cnt = c.getCount();
int minValue = 0;
int maxValue = 0;
for (int i = 0; i < cnt; i++) {
int glucoseValue = c.getInt(2);
series.add(i, glucoseValue);
if (i == 0 || glucoseValue < minValue)
minValue = glucoseValue;
if (glucoseValue > maxValue)
maxValue = glucoseValue;
c.moveToNext();
}
datasource.close();
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
dataset.addSeries(series);
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setColor(Color.BLUE);
renderer.setPointStyle(PointStyle.CIRCLE);
renderer.setFillPoints(true);
renderer.setLineWidth(3);
renderer.setDisplayChartValues(true);
renderer.setChartValuesTextSize(15);
renderer.setChartValuesTextAlign(Align.LEFT);
XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
mRenderer.addSeriesRenderer(renderer);
mRenderer.setShowGrid(true);
mRenderer.setGridColor(Color.BLACK);
mRenderer.setXLabels(cnt); // to control number of grid lines
mRenderer.setYLabels(cnt); // to control number of grid lines
mRenderer.setXLabelsColor(Color.YELLOW);
mRenderer.setPointSize(5);
mRenderer.setYLabelsAlign(Align.RIGHT);
mRenderer.setLegendTextSize(15);
mRenderer.setZoomButtonsVisible(true);
mRenderer.setYAxisMin(minValue - 2); // buffer bottom
mRenderer.setYAxisMax(maxValue + 3); // buffer top
// Populate the X labels with the dates and times
c.moveToFirst();
for (int d = 0; d < cnt; d++) {
timeStamp = c.getString(1);
date = timeStamp.substring(0, 5);
time = timeStamp.substring(9, 14);
if (date.equals(dateLast)) {
mRenderer.addXTextLabel(d, "\n" + time);
} else
mRenderer.addXTextLabel(d, "\n" + time + "\n" + date);
dateLast = date;
c.moveToNext();
}
c.close();
GraphicalView gview = ChartFactory.getTimeChartView(this, dataset,
mRenderer, "");
LinearLayout layout = (LinearLayout) findViewById(R.id.Chart);
layout.addView(gview);
For the first question, you can control the labels display using
renderer.setXLabels(approximateNumberOfLabels);
For the second question, the grid lines are displayed along the labels.
I just want to display several Charts in the same Panel. It doesn't matter which chart types I use (Column, Line, Pie etc). The result is that only the first chart has labels, no matter how many charts I try to display. See this screen shot:
On the second chart, the x- and y-axis labels are missing as well as the labels for the data sets. I tested in Chrome, Firefox and IE. Always the same.
Here is the code I use:
VerticalPanel panel=new VerticalPanel();
final int height = 400;
final int width = 1200;
Date d = new Date();
//message data
final DataTable msgData = DataTable.create();
msgData.addColumn(ColumnType.DATE, "date");
msgData.addColumn(ColumnType.NUMBER, "data one");
msgData.addColumn(ColumnType.NUMBER, "data two");
msgData.addRows(6);
for (int i = 0; i < 6; i++)
{
d.setTime(d.getTime() + (1000 * 60 * 60 * 24));
msgData.setValue(i, 0, d);
msgData.setValue(i, 1, i + 11);
msgData.setValue(i, 2, i + 12);
}
final Options options = Options.create();
options.setWidth(width);
options.setHeight(height);
options.setIsStacked(true);
options.setTitle("Chart One");
panel.add(new ColumnChart(msgData, options));
d = new Date();
//new data
final DataTable newData = DataTable.create();
newData.addColumn(ColumnType.DATE, "date");
newData.addColumn(ColumnType.NUMBER, "data three");
newData.addColumn(ColumnType.NUMBER, "data four");
newData.addRows(5);
for (int i = 0; i < 5; i++)
{
d.setTime(d.getTime() + (1000 * 60 * 60 * 24));
newData.setValue(i, 0, d);
newData.setValue(i, 1, i + 3);
newData.setValue(i, 2, i + 4);
}
final Options options_new = Options.create();
options_new.setWidth(width);
options_new.setHeight(height);
options_new.setIsStacked(true);
options_new.setTitle("Chart two");
panel.add(new ColumnChart(newData, options_new));
I checked the generated html with firebug. The charts are rendered using SVG and in the second chart there are just no svg-tags for the labels, while they exist in the first chart. So the missing labels are not cut off or hidden, but are not even created.
Thanks for your help