📄 attributevisualizationpanel.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/**
* AttributeVisualizationPanel.java
* Copyright (C) 2003 Ashraf M. Kibriya
*
*/
package weka.gui;
import java.io.FileReader;
import java.util.Random;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
//import java.awt.Image;
//import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JComboBox;
import weka.core.Attribute;
import weka.core.Instances;
import weka.core.AttributeStats;
import weka.core.Utils;
import weka.core.FastVector;
import weka.gui.visualize.PrintablePanel;
import weka.gui.visualize.PrintableComponent;
/**
* Creates a panel that shows a visualization of an
* attribute in a dataset. For nominal attribute it
* shows a bar plot, with each bar corresponding to
* each nominal value of the attribute with its height
* equal to the frequecy that value appears in the
* dataset. For numeric attributes, it displays a
* histogram. The width of an interval in the
* histogram is calculated using Scott's(1979)
* method: <br>
* intervalWidth = Max(1, 3.49*Std.Dev*numInstances^(1/3))
* Then the number of intervals is calculated by: <br>
* intervals = max(1, Math.round(Range/intervalWidth);
*
* @author Ashraf M. Kibriya (amk14@cs.waikato.ac.nz)
* @version $Revision: 1.1 $
*/
public class AttributeVisualizationPanel extends PrintablePanel {
/** This holds the current set of instances */
protected Instances m_data;
/**
* This holds the attribute stats of the current attribute on display. It is
* calculated in setAttribute(int idx) when it is called to set a new
* attribute index.
*/
protected AttributeStats m_as;
/** This holds the index of the current attribute on display and should be
* set through setAttribute(int idx).
*/
protected int m_attribIndex;
/**
* This holds the max value of the current attribute. In case of nominal
* attribute it is the highest count that a nominal value has in the
* attribute (given by m_as.nominalCounts[i]), otherwise in case of numeric
* attribute it is simply the maximum value present in the attribute (given by
* m_as.numericStats.max). It is used to calculate the ratio of the height of
* the bars with respect to the height of the display area.
*/
protected int m_maxValue;
/**
* This array holds the count (or height) for the each of the bars in a
* barplot or a histogram. In case of barplots (and current attribute being
* nominal) its length (and the number of bars) is equal to the number of
* nominal values in the current attribute, with each field of the array being
* equal to the count of each nominal that it represents (the count of ith
* nominal value of an attribute is given by m_as.nominalCounts[i]). Whereas,
* in case of histograms (and current attribute being numeric) the width of
* its intervals is calculated by Scott's(1979) method: <br>
* intervalWidth = Max(1, 3.49*Std.Dev*numInstances^(1/3))
* And the number of intervals by: <br>
* intervals = max(1, Math.round(Range/intervalWidth);
* Then each field of this array contains the number of values of the current
* attribute that fall in the histogram interval that it represents. <br>
* NOTE: The values of this array are only calculated if the class attribute
* is not set or if it is numeric.
*/
protected int m_histBarCounts[];
/**
* This array holds the per class count (or per class height) of the each of
* the bars in a barplot or a histogram.
* For nominal attributes the format is: <br>
* m_histBarClassCounts[nominalValue][classValue+1].
* For numeric attributes the format is: <br>
* m_histBarClassCounts[interval][classValues+1], <br>
* where the number of intervals is calculated by the Scott's method as
* mentioned above.
* The array is initialized to have 1+numClasses to accomodate for instances
* with missing class value. The ones with missing class value are displayed
* as a black sub par in a histogram or a barplot.
*
* NOTE: The values of this array are only calculated if the class attribute
* is set and it is nominal.
*/
int m_histBarClassCounts[][];
/**
* Contains the range of each bar in a histogram. It is used to work out the
* range of bar the mouse pointer is on in getToolTipText().
*/
protected double m_barRange;
/** Contains the current class index. */
protected int m_classIndex;
/** This stores the BarCalc or HistCalc thread while a new barplot or
* histogram is being calculated. */
private Thread m_hc;
/** True if the thread m_hc above is running. */
private boolean m_threadRun=false;
/** This stores and lets the user select a class attribute. It also has
* an entry "No Class" if the user does not want to set a class attribute
* for colouring.
*/
protected JComboBox m_colorAttrib;
/**
* Fontmetrics used to get the font size which is required for calculating
* displayable area size, bar height ratio and width of strings that are
* displayed on top of bars indicating their count.
*/
private FontMetrics m_fm;
/**
* Lock variable to synchronize the different threads running currently in
* this class. There are two to three threads in this class, AWT paint thread
* which is handled differently in paintComponent() which checks on
* m_threadRun to determine if it can perform full paint or not, the second
* thread is the main execution thread and the third is the one represented by
* m_hc which we start when we want to calculate the internal fields for a bar
* plot or a histogram.
*/
private Integer m_locker = new Integer(1);
//Image img;
/** Contains discrete colours for colouring of subbars of histograms and
* bar plots when the class attribute is set and is nominal
*/
private FastVector m_colorList = new FastVector();
/** default colour list */
private static final Color [] m_defaultColors = {Color.blue,
Color.red,
Color.cyan,
new Color(75, 123, 130),
Color.pink,
Color.green,
Color.orange,
new Color(255, 0, 255),
new Color(255, 0, 0),
new Color(0, 255, 0),
};
/**
* Constructor - If used then the class will not show the class selection
* combo box.
*/
public AttributeVisualizationPanel() {
this(false);
}
/**
* Constructor.
* @param showColouringOption - should be true if the class selection combo
* box is to be displayed with the histogram/barplot, or false otherwise.
* P.S: the combo box is always created it just won't be shown if
* showColouringOption is false.
*/
public AttributeVisualizationPanel(boolean showColouringOption) {
this.setFont( new Font("Default", Font.PLAIN, 9) );
m_fm = this.getFontMetrics( this.getFont() );
this.setToolTipText("");
FlowLayout fl= new FlowLayout(FlowLayout.LEFT);
this.setLayout(fl);
this.addComponentListener( new ComponentAdapter() {
public void componentResized(ComponentEvent ce) {
if(m_data!=null)
calcGraph();
}
});
m_colorAttrib = new JComboBox();
m_colorAttrib.addItemListener( new ItemListener() {
public void itemStateChanged(ItemEvent ie) {
if(ie.getStateChange()==ItemEvent.SELECTED) {
m_classIndex = m_colorAttrib.getSelectedIndex() - 1;
if (m_as != null) {
setAttribute(m_attribIndex);
}
}
}
});
if(showColouringOption) {
//m_colorAttrib.setVisible(false);
this.add(m_colorAttrib);
validate();
}
}
/**
* Sets the instances for use
*
* @param newins a set of Instances
*/
public void setInstances(Instances newins) {
m_attribIndex = 0;
m_as = null;
m_data = newins;
if(m_colorAttrib!=null) {
m_colorAttrib.removeAllItems();
m_colorAttrib.addItem("No class");
for(int i=0; i<m_data.numAttributes(); i++) {
String type = "";
switch (m_data.attribute(i).type()) {
case Attribute.NOMINAL:
type = "(Nom) ";
break;
case Attribute.NUMERIC:
type = "(Num) ";
break;
case Attribute.STRING:
type = "(Str) ";
break;
case Attribute.DATE:
type = "(Dat) ";
break;
default:
type = "(???) ";
}
m_colorAttrib.addItem(new String("Class: "+m_data.attribute(i).name()+
" " + type));
}
if (m_data.classIndex() >= 0) {
m_colorAttrib.setSelectedIndex(m_data.classIndex() + 1);
} else {
m_colorAttrib.setSelectedIndex(m_data.numAttributes());
}
//if (m_data.classIndex() >= 0) {
// m_colorAttrib.setSelectedIndex(m_data.classIndex());
//}
}
if (m_data.classIndex() >= 0) {
m_classIndex = m_data.classIndex();
} else {
m_classIndex = m_data.numAttributes()-1;
}
}
/**
* Returns the class selection combo box if the parent component wants to
* place it in itself or in some component other than this component.
*/
public JComboBox getColorBox() {
return m_colorAttrib;
}
/**
* Get the coloring (class) index for the plot
*
* @return an <code>int</code> value
*/
public int getColoringIndex() {
return m_classIndex; //m_colorAttrib.getSelectedIndex();
}
/**
* Set the coloring (class) index for the plot
*
* @param ci an <code>int</code> value
*/
public void setColoringIndex(int ci) {
m_classIndex = ci;
if(m_colorAttrib!=null)
m_colorAttrib.setSelectedIndex(ci + 1);
else
setAttribute(m_attribIndex);
}
/**
* Tells the panel which attribute to visualize.
*
* @param index The index of the attribute
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -