Reputation: 561
I am displaying normal distribution using JFreeChart, and I change the tick number to standard deviation; but I would also want there to always be 'mean' value in the middle from which ticks emerge. Cross-posted here.
So standard deviation = 2 ; mean = 1
-3 -1 1 3 5
Standard deviation = 5 ; mean = 15
0 5 10 15 20 25 30
JFreeChart.java
public class JFreeChartPanel extends JPanel {
private final XYPlot plot;
double mean = 0.0, sd = 1.0;
XYDataset dataset = initDataset();
NumberAxis domain = new NumberAxis("Y") {
@Override
protected double calculateLowestVisibleTickValue() {
double lowTickValue = super.calculateLowestVisibleTickValue();
if (mean % 2 == 1) {
return lowTickValue + 1;
} else {
return lowTickValue;
}
}
};
public JFreeChartPanel(){
JFreeChart chart = ChartFactory.createXYLineChart(
"Normal Distribution",
"X",
"PDF",
dataset,
PlotOrientation.VERTICAL,
false,
false,
false
);
plot=chart.getXYPlot();
domain.setAutoRangeStickyZero(false);
domain.setTickUnit(new NumberTickUnit(sd));
plot.setDomainAxis(domain);
final ChartPanel chartPanel = new ChartPanel(chart);
setLayout(new BorderLayout());
add(chartPanel);
}
private XYDataset initDataset() {
double minX=mean-(4*sd),maxX=mean+(4*sd);
Function2D normal = new NormalDistributionFunction2D(mean, sd);
XYDataset dataset = DatasetUtilities.sampleFunction2D(normal, minX, maxX, 100, "Normal");
return dataset;
}
public double getMean() {
return mean;
}
public void setMean(double mean) {
this.mean = mean;
plot.setDataset(initDataset());
}
public double getSd() {
return sd;
}
public void setSd(double sd) {
this.sd = sd;
domain.setTickUnit(new NumberTickUnit(sd));
plot.setDataset(initDataset());
}
}
UI.java
public class UI extends javax.swing.JFrame {
public UI() {
initComponents();
}
@SuppressWarnings("unchecked")
private void initComponents() {
Auto-generated Netbeans GUI COde
}
public void updateMean()
{
try{
double m = Double.parseDouble(mean.getText());
jFreeChartPanel.setMean(m);
}catch(Exception e){
}
}
public void updateSd()
{
try{
double sd = Double.parseDouble(standardDeviation.getText());
jFreeChartPanel.setSd(sd);
}catch(Exception e){
}
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new UI().setVisible(true);
}
});
}
private javax.swing.JPanel inputPanel;
private main.JFreeChartPanel jFreeChartPanel;
private javax.swing.JPanel jPanel1;
private javax.swing.JToggleButton jToggleButton1;
private javax.swing.JTextField mean;
private javax.swing.JLabel meanLabel;
private javax.swing.JTextField standardDeviation;
private javax.swing.JLabel standardDeviationLabel;
}
Upvotes: 2
Views: 1109
Reputation: 205875
Starting from this example, I made the following changes, adapted from yours, to get the result illustrated below for µ=15 and σ=5:
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
…
private double mean = 15.0, sigma = 5.0;
…
private XYDataset initDataset() {
double minX = mean - (3 * sigma), maxX = mean + (3 * sigma);
Function2D normal = new NormalDistributionFunction2D(mean, sigma);
XYDataset dataset = DatasetUtilities.sampleFunction2D(normal, minX, maxX, 100, "Normal");
return dataset;
}
…
public JFreeChartPanel() {
…
plot = chart.getXYPlot();
NumberAxis domain = (NumberAxis) plot.getDomainAxis();
domain.setTickUnit(new NumberTickUnit(sigma));
…
}
Your other case, µ=1 and σ=2, requires overriding the NumberAxis
method calculateLowestVisibleTickValue()
to make ticks fall on odd values.
NumberAxis domain = new NumberAxis("Y") {
@Override
protected double calculateLowestVisibleTickValue() {
double lowTickValue = super.calculateLowestVisibleTickValue();
if (mean % 2 == 1) {
return lowTickValue + 1;
} else {
return lowTickValue;
}
}
};
domain.setTickUnit(new NumberTickUnit(sigma));
plot = chart.getXYPlot();
plot.setDomainAxis(domain);
Why [is] the graph is slightly skewed for mean 3 and sd 1 also for mean 6 sd 2, mean 9 sd 3 and so on; here is a picture showing this.
As discussed here, there's "A flag that affects the size of the margins added to the axis range when the range is determined automatically."
domain.setAutoRangeStickyZero(false);
I've added…code.
Adding and instance of your revision 6 JFreeChartPanel
to a JFrame
with µ=1 and σ=2 produces the following result:
This happens with higher mean.
You can exclude zero from the auto-range.
domain.setAutoRangeIncludesZero(false);
Upvotes: 2