List of usage examples for weka.core Instances instance
publicInstance instance(int index)
From source file:lu.lippmann.cdb.ext.hydviga.ui.GapsUIUtil.java
License:Open Source License
public static ChartPanel buildGapChartPanelWithCorrection(final Instances pdataSet, final int dateIdx, final Attribute attr, final int gapsize, final int position, final GapFiller gapFiller, final java.util.Collection<String> attrs) throws Exception { final Instances dataSetWithTheGap = new Instances(pdataSet); for (int i = position; i < position + gapsize; i++) dataSetWithTheGap.instance(i).setMissing(attr); int[] arr = new int[] { attr.index(), dateIdx }; for (final String sss : attrs) { arr = ArraysUtil.concat(arr, new int[] { dataSetWithTheGap.attribute(sss).index() }); }/*from ww w. j a v a2s. c om*/ Instances filteredDsWithTheGap = WekaDataProcessingUtil.buildFilteredByAttributesDataSet(dataSetWithTheGap, arr); filteredDsWithTheGap = WekaDataProcessingUtil.buildFilteredDataSet(filteredDsWithTheGap, 0, filteredDsWithTheGap.numAttributes() - 1, Math.max(0, position - GapsUtil.VALUES_BEFORE_AND_AFTER_RATIO * gapsize), Math.min(position + gapsize + GapsUtil.VALUES_BEFORE_AND_AFTER_RATIO * gapsize, filteredDsWithTheGap.numInstances() - 1)); final Instances completedds = gapFiller.fillGaps(filteredDsWithTheGap); final Instances diff = WekaTimeSeriesUtil.buildDiff(filteredDsWithTheGap, completedds); Instances filteredDsWithoutTheGap = WekaDataProcessingUtil.buildFilteredByAttributesDataSet(pdataSet, arr); filteredDsWithoutTheGap = WekaDataProcessingUtil.buildFilteredDataSet(filteredDsWithoutTheGap, 0, filteredDsWithoutTheGap.numAttributes() - 1, Math.max(0, position - GapsUtil.VALUES_BEFORE_AND_AFTER_RATIO * gapsize), Math.min(position + gapsize + GapsUtil.VALUES_BEFORE_AND_AFTER_RATIO * gapsize, filteredDsWithoutTheGap.numInstances() - 1)); diff.insertAttributeAt(new Attribute(attr.name() + "_orig"), diff.numAttributes()); for (int i = 0; i < filteredDsWithoutTheGap.numInstances(); i++) { diff.instance(i).setValue(diff.numAttributes() - 1, filteredDsWithoutTheGap.instance(i).value(filteredDsWithoutTheGap.attribute(attr.name()))); } //System.out.println(attr.name()+"\n"+diff.toSummaryString()); final java.util.List<String> toRemove = new java.util.ArrayList<String>(); for (int j = 0; j < diff.numAttributes(); j++) { final String consideredAttrName = diff.attribute(j).name(); if (!consideredAttrName.contains("timestamp") && !consideredAttrName.contains(attr.name())) toRemove.add(consideredAttrName); } diff.setClassIndex(-1); for (final String ssss : toRemove) diff.deleteAttributeAt(diff.attribute(ssss).index()); //System.out.println(attr.name()+"\n"+diff.toSummaryString()); final ChartPanel cp = TimeSeriesChartUtil.buildChartPanelForAllAttributes(diff, false, WekaDataStatsUtil.getFirstDateAttributeIdx(diff), null); final XYPlot xyp = (XYPlot) cp.getChart().getPlot(); xyp.getDomainAxis().setLabel(""); xyp.getRangeAxis().setLabel(""); final Marker gapBeginMarker = new ValueMarker( dataSetWithTheGap.instance(Math.max(0, position - 1)).value(dateIdx)); gapBeginMarker.setPaint(Color.RED); gapBeginMarker.setLabel("Gap begin"); gapBeginMarker.setLabelAnchor(RectangleAnchor.TOP_LEFT); gapBeginMarker.setLabelTextAnchor(TextAnchor.TOP_RIGHT); cp.getChart().getXYPlot().addDomainMarker(gapBeginMarker); final Marker gapEndMarker = new ValueMarker(dataSetWithTheGap .instance(Math.min(dataSetWithTheGap.numInstances() - 1, position + gapsize)).value(dateIdx)); gapEndMarker.setPaint(Color.RED); gapEndMarker.setLabel("Gap end"); gapEndMarker.setLabelAnchor(RectangleAnchor.TOP_RIGHT); gapEndMarker.setLabelTextAnchor(TextAnchor.TOP_LEFT); cp.getChart().getXYPlot().addDomainMarker(gapEndMarker); addExportPopupMenu(diff, cp); return cp; }
From source file:lu.lippmann.cdb.ext.hydviga.ui.HydroDatasetView.java
License:Open Source License
private void updateFiltersPane(final Instances instances) throws Exception { filterPanel.removeAll();/*w ww . jav a2s.c o m*/ gbc.gridx = 0; gbc.gridy = 0; final int numAttributes = instances.numAttributes(); final RangeSlider[] rangeSliders = new RangeSlider[numAttributes]; final JComboBox[] nominalCombos = new JComboBox[numAttributes]; boolean hasNumeric = false; boolean hasDate = false; for (int i = 0; i < numAttributes; i++) { final int attrIdx = i; if ((WekaDataStatsUtil.isInteger(instances, i)) || instances.attribute(i).isDate()) { hasNumeric = hasNumeric || (instances.attribute(i).isNumeric() && !instances.attribute(i).isDate()); hasDate = hasDate || instances.attribute(i).isDate(); final long[] minmax = WekaDataStatsUtil.getMinMaxForAttribute(instances, i); if (Math.abs(minmax[1] - minmax[0]) < 0.00001) continue; if (instances.attribute(i).isDate()) { minmax[0] = (int) (minmax[0] / (1000l)); minmax[1] = (int) (minmax[1] / (1000l)); } long[] oldminmax; try { final Attribute goodAttr = notFilteredDataSet.attribute(instances.attribute(i).name()); oldminmax = WekaDataStatsUtil.getMinMaxForAttribute(notFilteredDataSet, goodAttr.index()); if (instances.attribute(i).isDate()) { oldminmax[0] = (int) (oldminmax[0] / (1000l)); oldminmax[1] = (int) (oldminmax[1] / (1000l)); } } catch (Throwable t) { oldminmax = minmax; } rangeSliders[i] = new RangeSlider(); //System.out.println("pref size -> "+this.scrollPane.getPreferredSize().getWidth()); rangeSliders[i].setPreferredSize(new Dimension(600, rangeSliders[i].getPreferredSize().height)); rangeSliders[i].setMinimum((int) oldminmax[0]); rangeSliders[i].setMaximum((int) oldminmax[1]); rangeSliders[i].setValue((int) minmax[0]); rangeSliders[i].setUpperValue((int) minmax[1]); // hack... rangeSliders[i].setValue((int) minmax[0]); rangeSliders[i].setUpperValue((int) minmax[1]); if (!instances.attribute(i).isDate()) { rangeSliders[i].setPaintTicks(true); rangeSliders[i].setPaintLabels(true); final int rangeWidth = (int) (oldminmax[1] - oldminmax[0]); rangeSliders[i].setMinorTickSpacing(rangeWidth / 10); rangeSliders[i].setMajorTickSpacing(rangeWidth / 2); } rangeSliders[i].addChangeListener(new ChangeListener() { @Override public void stateChanged(final ChangeEvent e) { if (!rangeSliders[attrIdx].getValueIsAdjusting()) { processfilters(rangeSliders, nominalCombos, instances.attribute(attrIdx).name(), attrIdx); } else { if (instances.attribute(attrIdx).isDate()) { final Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(rangeSliders[attrIdx].getValue() * 1000l); final String minDate = FormatterUtil.DATE_FORMAT.format(cal.getTime()); cal.setTimeInMillis(rangeSliders[attrIdx].getUpperValue() * 1000l); final String maxDate = FormatterUtil.DATE_FORMAT.format(cal.getTime()); rangeSliders[attrIdx].setBorder(new TitledBorder(instances.attribute(attrIdx).name() + " [" + minDate + " - " + maxDate + "]")); } else { rangeSliders[attrIdx].setBorder(new TitledBorder(instances.attribute(attrIdx).name() + " [" + rangeSliders[attrIdx].getValue() + " - " + rangeSliders[attrIdx].getUpperValue() + "]")); } } } }); if (instances.attribute(i).isDate()) { filterPanel.add(rangeSliders[i], gbc); gbc.gridx++; final Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(rangeSliders[i].getValue() * 1000l); final String minDate = FormatterUtil.DATE_FORMAT.format(cal.getTime()); cal.setTimeInMillis(rangeSliders[i].getUpperValue() * 1000l); final String maxDate = FormatterUtil.DATE_FORMAT.format(cal.getTime()); rangeSliders[i].setBorder(new TitledBorder( instances.attribute(i).name() + " [" + minDate + " - " + maxDate + "]")); } else { filterPanel.add(rangeSliders[i], gbc); gbc.gridx++; rangeSliders[i].setBorder(new TitledBorder(instances.attribute(i).name() + " [" + rangeSliders[i].getValue() + " - " + rangeSliders[i].getUpperValue() + "]")); } } else { rangeSliders[i] = null; } } for (int i = 0; i < numAttributes; i++) { if (instances.attribute(i).isNominal()) { final ArrayList<String> possibleValuesList = new ArrayList<String>(); final Enumeration<?> es = notFilteredDataSet .attribute(notFilteredDataSet.attribute(instances.attribute(i).name()).index()) .enumerateValues(); possibleValuesList.add(ALL_VAL); while (es.hasMoreElements()) { possibleValuesList.add(es.nextElement().toString().trim()); } if (possibleValuesList.size() == 2) continue; // only one choice, no filter needed! nominalCombos[i] = new JComboBox(possibleValuesList.toArray()); if (WekaDataStatsUtil.getPresentValuesForNominalAttribute(instances, i).size() == 1) { nominalCombos[i].setSelectedItem(instances.instance(0).stringValue(i)); } nominalCombos[i].setBorder(new TitledBorder(instances.attribute(i).name())); final int nominalAttrIdx = i; nominalCombos[i].addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { processfilters(rangeSliders, nominalCombos, instances.attribute(nominalAttrIdx).name(), nominalAttrIdx); } }); filterPanel.add(nominalCombos[i], gbc); gbc.gridx++; } } filterPanel.setVisible(gbc.gridx > 0); filterPanel.updateUI(); scrollPane.setVisible(gbc.gridx > 0); scrollPane.updateUI(); /* automatically set the timestamp range */ /*SwingUtilities.invokeLater(new Runnable() { @Override public void run() { for (int i = 0 ; i < numAttributes ; i++) { if (rangeSliders[i]!=null&&instances.attribute(i).isDate()) { System.out.println(rangeSliders[i].getValue()+" "+rangeSliders[i].getMinimum()+" "+rangeSliders[i].getUpperValue()+" "+rangeSliders[i].getMaximum()); if (rangeSliders[i].getValue()==rangeSliders[i].getMinimum()&&rangeSliders[i].getUpperValue()==rangeSliders[i].getMaximum()) { final int toadd=(rangeSliders[i].getMaximum()-rangeSliders[i].getMinimum())/2; rangeSliders[i].setValue(rangeSliders[i].getMinimum()+toadd); break; } } } } });*/ }
From source file:lu.lippmann.cdb.ext.hydviga.util.GapsUtil.java
License:Open Source License
public static String measureHighMiddleLowInterval(final Instances ds, final int attrIdx, final int pos) { final double[] minmax = WekaDataStatsUtil.getMinMaxForAttributeAsArrayOfDoubles(ds, attrIdx); final double min = minmax[0]; final double max = minmax[1]; final double stepmin = ((max - min) / 3) + min; final double stepmax = (2 * (max - min) / 3) + min; final double val = ds.instance(pos).value(attrIdx); String res = "n/a"; if (val > stepmax) res = "high"; else if (val > stepmin) res = "middle"; else/*from www. jav a 2s. c o m*/ res = "low"; //System.out.println(ds.toSummaryString()); //System.out.println("idx="+attrIdx+" pos="+pos+" min="+min+" max="+max+" -> stepmin="+stepmin+" stepmax="+stepmax+" -> val="+val+" res="+res); return res; }
From source file:lu.lippmann.cdb.ext.hydviga.util.TransformTimeSeries.java
License:Open Source License
/** * Main method./* www . ja v a 2 s .c o m*/ * @param args command line arguments */ public static final void main(final String[] args) { try { final Instances dataSet = WekaDataAccessUtil.loadInstancesFromARFFOrCSVFile(new File("." + File.separatorChar + "data_fake" + File.separatorChar + "all_valid_q_series_complete2.arff")); System.out.println(dataSet.toSummaryString()); final int numAttributes = dataSet.numAttributes(); final int numInstances = dataSet.numInstances(); for (int i = 0; i < numAttributes; i++) { final int i_bis = (int) (Math.random() * (double) (numAttributes - 3)); final int i_tri = (int) (Math.random() * (double) (numAttributes - 3)); for (int j = 0; j < numInstances; j++) { final Instance instance_j = dataSet.instance(j); if (instance_j.isMissing(i)) continue; if (instance_j.isMissing(i_bis)) continue; if (instance_j.isMissing(i_tri)) continue; final double iValue = instance_j.value(i); final double iBisValue = instance_j.value(i_bis); final double iTriValue = instance_j.value(i_tri); instance_j.setValue(i, (iValue + iBisValue + iTriValue)); } } WekaDataAccessUtil.saveInstancesIntoARFFFile(dataSet, new File("." + File.separatorChar + "data_fake" + File.separatorChar + "all_valid_q_series_complete2_fake.arff")); } catch (final Exception e) { e.printStackTrace(); } }
From source file:lu.lippmann.cdb.lab.beta.util.WekaUtil2.java
License:Open Source License
/** * Generate the centroid coordinates based * on it's members (objects assigned to the cluster of the centroid) and the distance * function being used./*from w w w . j a v a2s. c o m*/ * @return the centroid */ public static MixedCentroid computeMixedCentroid(final boolean preserveOrder, final NormalizableDistance distanceFunction, final Instances numericInstances, final Instances originalInstances, final int clusterIndex) { final int numInstances = numericInstances.numInstances(); final int numAttributes = numericInstances.numAttributes(); final Map<TupleSI, Integer> addedAttr = new HashMap<TupleSI, Integer>(); if (numInstances == 1) { Instance uniqueNumInstance = numericInstances.firstInstance(); Instance uniqueMixInstance = originalInstances.firstInstance(); double[] centroid = uniqueNumInstance.toDoubleArray(); for (int i = 0; i < uniqueMixInstance.numAttributes(); i++) { if (!uniqueMixInstance.attribute(i).isNumeric()) { final String catVal = uniqueMixInstance.attribute(i).value((int) uniqueMixInstance.value(i)); addedAttr.put(new TupleSI(catVal, i), 1); } } return new MixedCentroid(clusterIndex, centroid, addedAttr); } final double[] vals = new double[numAttributes]; //used only for Manhattan Distance Instances sortedMembers = null; int middle = 0; boolean dataIsEven = false; final boolean isManhattanDist = (distanceFunction instanceof ManhattanDistance); final boolean isEuclideanDist = (distanceFunction instanceof EuclideanDistance); if (isManhattanDist) { middle = (numInstances - 1) / 2; dataIsEven = ((numInstances % 2) == 0); if (preserveOrder) { sortedMembers = numericInstances; } else { sortedMembers = new Instances(numericInstances); } } for (int j = 0; j < numAttributes; j++) { //in case of Euclidian distance the centroid is the mean point //in case of Manhattan distance the centroid is the median point //in both cases, if the attribute is nominal, the centroid is the mode if (isEuclideanDist) { vals[j] = numericInstances.meanOrMode(j); for (int i = 0; i < numInstances; i++) { if (!originalInstances.attribute(j).isNumeric()) { final Instance instance = originalInstances.instance(i); final String catVal = instance.attribute(j).value((int) instance.value(j)); //Initialize map final TupleSI key = new TupleSI(catVal, j); if (!addedAttr.containsKey(key)) addedAttr.put(key, 0); addedAttr.put(key, addedAttr.get(key) + 1); } } } else if (isManhattanDist) { sortedMembers.kthSmallestValue(j, middle + 1); vals[j] = sortedMembers.instance(middle).value(j); if (dataIsEven) { sortedMembers.kthSmallestValue(j, middle + 2); vals[j] = (vals[j] + sortedMembers.instance(middle + 1).value(j)) / 2; } } else { throw new IllegalStateException("Not handled distance ..."); } } return new MixedCentroid(clusterIndex, vals, addedAttr); }
From source file:lu.lippmann.cdb.lab.beta.util.WekaUtil2.java
License:Open Source License
/** * /*from ww w . j a v a 2s. com*/ * @param instances * @param instance */ public static void removeFromInstances(Instances instances, Instance instance) { InstanceComparator cp = new InstanceComparator(); for (int i = 0; i < instances.numInstances(); i++) { Instance cinstance = instances.instance(i); if (cp.compare(cinstance, instance) == 0) { instances.remove(cinstance); break; } } }
From source file:lu.lippmann.cdb.lab.beta.util.WekaUtil2.java
License:Open Source License
/** * /*from ww w . j av a2 s . co m*/ * @param wekaClusterer * @param instances * @return * @throws Exception */ public static List<IndexedInstance> computeClusters(final Clusterer wekaClusterer, final Instances instances) throws Exception { final Instances ii = new Instances(instances); ii.setClassIndex(-1); wekaClusterer.buildClusterer(ii); final ClusterEvaluation eval = new ClusterEvaluation(); eval.setClusterer(wekaClusterer); eval.evaluateClusterer(ii); final int clustersCount = eval.getNumClusters(); final List<IndexedInstance> clustersList = new ArrayList<IndexedInstance>(clustersCount); //Initialize instances for (int k = 0; k < clustersCount; k++) { clustersList.add(new IndexedInstance(new Instances(instances, 0), new HashMap<Integer, Integer>())); } final double[] ass = eval.getClusterAssignments(); if (ass.length != ii.numInstances()) throw new IllegalStateException(); for (int i = 0; i < ass.length; i++) { IndexedInstance idxi = clustersList.get((int) ass[i]); idxi.getInstances().add(instances.instance(i)); int pos = idxi.getInstances().size() - 1; idxi.getMapOrigIndex().put(pos, i); } return clustersList; }
From source file:lu.lippmann.cdb.lab.mds.ClassicMDS.java
License:Open Source License
public static void main(String[] args) throws Exception { final Instances ds = WekaDataAccessUtil.loadInstancesFromARFFOrCSVFile( //new File("./samples/csv/uci/zoo.csv")); new File("./samples/csv/test50bis.csv")); //new File("./samples/arff/UCI/cmc.arff")); //new File("./samples/csv/direct-marketing-bank-reduced.csv")); //new File("./samples/csv/bank.csv")); //new File("./samples/csv/preswissroll.csv")); //new File("./samples/csv/preswissroll-mod4.csv")); ds.setClassIndex(-1);// ww w . j a v a 2s .co m final int N = ds.size(); final int M = ds.numAttributes(); SimpleMatrix dist = new SimpleMatrix(N, N); for (int i = 0; i < N; i++) { for (int j = i + 1; j < N; j++) { Instance xi = ds.instance(i); Instance xj = ds.instance(j); double d = 0, s = 0, a = 0, b = 0; for (int k = 1; k < M; k++) { s += xi.value(k) * xj.value(k); a += xi.value(k) * xi.value(k); b += xi.value(k) * xi.value(k); } d = 1 - s / (Math.sqrt(a) * Math.sqrt(b)); dist.set(i, j, d); dist.set(j, i, d); } } final MDSResult res = ClassicMDS.doMDSV1(ds, dist); JXPanel p2 = MDSViewBuilder.buildMDSViewFromDataSet(ds, res, 5000, null); p2.setPreferredSize(new Dimension(800, 600)); final JXFrame f = new JXFrame(); f.setPreferredSize(new Dimension(1024, 768)); final Container c = f.getContentPane(); c.add(p2); f.pack(); f.setVisible(true); f.setDefaultCloseOperation(JXFrame.EXIT_ON_CLOSE); System.out.println("Kruskal stress : =" + getKruskalStressFromMDSResult(res)); }
From source file:lu.lippmann.cdb.lab.mds.MDSViewBuilder.java
License:Open Source License
/** * // ww w. j a v a2 s. co m */ public static JXPanel buildMDSViewFromDataSet(final Instances instances, final MDSResult mdsResult, final int maxInstances, final Listener<Instances> listener, final String... attrNameToUseAsPointTitle) throws Exception { final XYSeriesCollection dataset = new XYSeriesCollection(); final JFreeChart chart = ChartFactory.createScatterPlot("", // title "X", "Y", // axis labels dataset, // dataset PlotOrientation.VERTICAL, attrNameToUseAsPointTitle.length == 0, // legend? true, // tooltips? yes false // URLs? no ); final XYPlot xyPlot = (XYPlot) chart.getPlot(); xyPlot.setBackgroundPaint(Color.WHITE); xyPlot.getDomainAxis().setTickLabelsVisible(false); xyPlot.getRangeAxis().setTickLabelsVisible(false); //FIXME : should be different for Shih if (!mdsResult.isNormalized()) { String stress = FormatterUtil.DECIMAL_FORMAT .format(ClassicMDS.getKruskalStressFromMDSResult(mdsResult)); chart.setTitle(mdsResult.getCInstances().isCollapsed() ? "Collapsed MDS(Instances=" + maxInstances + ",Stress=" + stress + ")" : "MDS(Stress=" + stress + ")"); } else { chart.setTitle(mdsResult.getCInstances().isCollapsed() ? "Collapsed MDS(Instances=" + maxInstances + ")" : "MDS"); } final SimpleMatrix coordinates = mdsResult.getCoordinates(); buildFilteredSeries(mdsResult, xyPlot, attrNameToUseAsPointTitle); final ChartPanel chartPanel = new ChartPanel(chart); chartPanel.setMouseWheelEnabled(true); chartPanel.setPreferredSize(new Dimension(1200, 900)); chartPanel.setBorder(new TitledBorder("MDS Projection")); chartPanel.setBackground(Color.WHITE); final JButton selectionButton = new JButton("Select data"); selectionButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { final org.jfree.data.Range XDomainRange = xyPlot.getDomainAxis().getRange(); final org.jfree.data.Range YDomainRange = xyPlot.getRangeAxis().getRange(); final Instances cInstances = mdsResult.getCollapsedInstances(); final Instances selectedInstances = new Instances(cInstances, 0); List<Instances> clusters = null; if (mdsResult.getCInstances().isCollapsed()) { clusters = mdsResult.getCInstances().getCentroidMap().getClusters(); } for (int i = 0; i < cInstances.numInstances(); i++) { final Instance centroid = instances.instance(i); if (XDomainRange.contains(coordinates.get(i, 0)) && YDomainRange.contains(coordinates.get(i, 1))) { if (mdsResult.getCInstances().isCollapsed()) { if (clusters != null) { final Instances elementsOfCluster = clusters.get(i); final int nbElements = elementsOfCluster.numInstances(); for (int k = 0; k < nbElements; k++) { selectedInstances.add(elementsOfCluster.get(k)); } } } else { selectedInstances.add(centroid); } } } if (listener != null) { listener.onAction(selectedInstances); } } }); final JXPanel allPanel = new JXPanel(); allPanel.setLayout(new BorderLayout()); allPanel.add(chartPanel, BorderLayout.CENTER); final JXPanel southPanel = new JXPanel(); southPanel.add(selectionButton); allPanel.add(southPanel, BorderLayout.SOUTH); return allPanel; }
From source file:lu.lippmann.cdb.lab.mds.MDSViewBuilder.java
License:Open Source License
/** * //w w w . j a v a 2 s . co m */ private static void buildFilteredSeries(final MDSResult mdsResult, final XYPlot xyPlot, final String... attrNameToUseAsPointTitle) throws Exception { final CollapsedInstances distMdsRes = mdsResult.getCInstances(); final Instances instances = distMdsRes.getInstances(); final SimpleMatrix coordinates = mdsResult.getCoordinates(); final Instances collapsedInstances = mdsResult.getCollapsedInstances(); int maxSize = 0; if (distMdsRes.isCollapsed()) { final List<Instances> clusters = distMdsRes.getCentroidMap().getClusters(); final int nbCentroids = clusters.size(); maxSize = clusters.get(0).size(); for (int i = 1; i < nbCentroids; i++) { final int currentSize = clusters.get(i).size(); if (currentSize > maxSize) { maxSize = currentSize; } } } Attribute clsAttribute = null; int nbClass = 1; if (instances.classIndex() != -1) { clsAttribute = instances.classAttribute(); nbClass = clsAttribute.numValues(); } final XYSeriesCollection dataset = (XYSeriesCollection) xyPlot.getDataset(); final int fMaxSize = maxSize; final List<XYSeries> lseries = new ArrayList<XYSeries>(); //No class : add one dummy serie if (nbClass <= 1) { lseries.add(new XYSeries("Serie #1", false)); } else { //Some class : add one serie per class for (int i = 0; i < nbClass; i++) { lseries.add(new XYSeries(clsAttribute.value(i), false)); } } dataset.removeAllSeries(); /** * Initialize filtered series */ final List<Instances> filteredInstances = new ArrayList<Instances>(); for (int i = 0; i < lseries.size(); i++) { filteredInstances.add(new Instances(collapsedInstances, 0)); } final Map<Tuple<Integer, Integer>, Integer> correspondanceMap = new HashMap<Tuple<Integer, Integer>, Integer>(); for (int i = 0; i < collapsedInstances.numInstances(); i++) { final Instance oInst = collapsedInstances.instance(i); int indexOfSerie = 0; if (oInst.classIndex() != -1) { if (distMdsRes.isCollapsed()) { indexOfSerie = getStrongestClass(i, distMdsRes); } else { indexOfSerie = (int) oInst.value(oInst.classAttribute()); } } lseries.get(indexOfSerie).add(coordinates.get(i, 0), coordinates.get(i, 1)); filteredInstances.get(indexOfSerie).add(oInst); if (distMdsRes.isCollapsed()) { correspondanceMap.put(new Tuple<Integer, Integer>(indexOfSerie, filteredInstances.get(indexOfSerie).numInstances() - 1), i); } } final List<Paint> colors = new ArrayList<Paint>(); for (final XYSeries series : lseries) { dataset.addSeries(series); } if (distMdsRes.isCollapsed()) { final XYLineAndShapeRenderer xyRenderer = new XYLineAndShapeRenderer(false, true) { private static final long serialVersionUID = -6019883886470934528L; @Override public void drawItem(Graphics2D g2, XYItemRendererState state, java.awt.geom.Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot, ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset, int series, int item, CrosshairState crosshairState, int pass) { if (distMdsRes.isCollapsed()) { final Integer centroidIndex = correspondanceMap .get(new Tuple<Integer, Integer>(series, item)); final Instances cluster = distMdsRes.getCentroidMap().getClusters().get(centroidIndex); int size = cluster.size(); final int shapeSize = (int) (MAX_POINT_SIZE * size / fMaxSize + 1); final double x1 = plot.getDataset().getX(series, item).doubleValue(); final double y1 = plot.getDataset().getY(series, item).doubleValue(); Map<Object, Integer> mapRepartition = new HashMap<Object, Integer>(); mapRepartition.put("No class", size); if (cluster.classIndex() != -1) { mapRepartition = WekaDataStatsUtil.getClassRepartition(cluster); } final RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); final RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); final double fx = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation); final double fy = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation); setSeriesShape(series, new Ellipse2D.Double(-shapeSize / 2, -shapeSize / 2, shapeSize, shapeSize)); super.drawItem(g2, state, dataArea, info, plot, domainAxis, rangeAxis, dataset, series, item, crosshairState, pass); //Draw pie if (ENABLE_PIE_SHART) { createPieChart(g2, (int) (fx - shapeSize / 2), (int) (fy - shapeSize / 2), shapeSize, mapRepartition, size, colors); } } else { super.drawItem(g2, state, dataArea, info, plot, domainAxis, rangeAxis, dataset, series, item, crosshairState, pass); } } }; xyPlot.setRenderer(xyRenderer); } final XYToolTipGenerator gen = new XYToolTipGenerator() { @Override public String generateToolTip(XYDataset dataset, int series, int item) { if (distMdsRes.isCollapsed()) { final StringBuilder res = new StringBuilder("<html>"); final Integer centroidIndex = correspondanceMap.get(new Tuple<Integer, Integer>(series, item)); final Instance centroid = distMdsRes.getCentroidMap().getCentroids().get(centroidIndex); final Instances cluster = distMdsRes.getCentroidMap().getClusters().get(centroidIndex); //Set same class index for cluster than for original instances //System.out.println("Cluster index = " + cluster.classIndex() + "/" + instances.classIndex()); cluster.setClassIndex(instances.classIndex()); Map<Object, Integer> mapRepartition = new HashMap<Object, Integer>(); mapRepartition.put("No class", cluster.size()); if (cluster.classIndex() != -1) { mapRepartition = WekaDataStatsUtil.getClassRepartition(cluster); } res.append(InstanceFormatter.htmlFormat(centroid, false)).append("<br/>"); for (final Map.Entry<Object, Integer> entry : mapRepartition.entrySet()) { if (entry.getValue() != 0) { res.append("Class :<b>'" + StringEscapeUtils.escapeHtml(entry.getKey().toString()) + "</b>' -> " + entry.getValue()).append("<br/>"); } } res.append("</html>"); return res.toString(); } else { //return InstanceFormatter.htmlFormat(filteredInstances.get(series).instance(item),true); return InstanceFormatter.shortHtmlFormat(filteredInstances.get(series).instance(item)); } } }; final Shape shape = new Ellipse2D.Float(0f, 0f, MAX_POINT_SIZE, MAX_POINT_SIZE); ((XYLineAndShapeRenderer) xyPlot.getRenderer()).setUseOutlinePaint(true); for (int p = 0; p < nbClass; p++) { xyPlot.getRenderer().setSeriesToolTipGenerator(p, gen); ((XYLineAndShapeRenderer) xyPlot.getRenderer()).setLegendShape(p, shape); xyPlot.getRenderer().setSeriesOutlinePaint(p, Color.BLACK); } for (int ii = 0; ii < nbClass; ii++) { colors.add(xyPlot.getRenderer().getItemPaint(ii, 0)); } if (attrNameToUseAsPointTitle.length > 0) { final Attribute attrToUseAsPointTitle = instances.attribute(attrNameToUseAsPointTitle[0]); if (attrToUseAsPointTitle != null) { final XYItemLabelGenerator lg = new XYItemLabelGenerator() { @Override public String generateLabel(final XYDataset dataset, final int series, final int item) { return filteredInstances.get(series).instance(item).stringValue(attrToUseAsPointTitle); } }; xyPlot.getRenderer().setBaseItemLabelGenerator(lg); xyPlot.getRenderer().setBaseItemLabelsVisible(true); } } }