Aligning domain axis with histogram bins

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
Gxb0514
Posts: 10
Joined: Mon Dec 02, 2013 2:30 am
antibot: No, of course not.

Aligning domain axis with histogram bins

Post by Gxb0514 » Tue Dec 03, 2013 3:23 am

All

would like to seek a little help and see if what I am trying to do is even doable. I am plotting a histogram as per source code snippet below

Code: Select all

 public GARunStatisticsHistogramPanel(GAMultiRunStatisticsObject MSO) {
    	//create the histogram data
    	this.MSO = MSO;
    	dataset = new HistogramDataset();
    	dataset.addSeries("Generation Solution Found", formatHistogramData(MSO.getGenSolutionFoundVector()), 100,1,101); //(series ID, data, number of bins (granularity), lowest, highest)
        init();
    }
    
    private void init(){
    	setHistogramStatistics();
    	JFreeChart chart = createChart(dataset);
        ChartPanel panel = new ChartPanel(chart);
        panel.setMouseWheelEnabled(true);
        panel.setPreferredSize(new java.awt.Dimension(1200, 800));
        setLayout(new BorderLayout()); 					//set layout and add to current content pane
        add(panel, BorderLayout.CENTER);
        add(getIndicatorPanel(), BorderLayout.SOUTH);
    }

    public double[] formatHistogramData(Vector<Integer> data) {
        double histData[] = new double[data.size()];	
        for (int z=0; z<data.size(); z++){ // count number of occurrences of each histogram bin value
           histData[z] = data.get(z).doubleValue(); //need to subtract 1 to account for missing zero bin
        }
        return histData;
      }// end createCategoryData function
    
   protected void setHistogramStatistics(){
       int modeIndex = 0;
       int modeValue = 0;
       for (int i=0; i<dataset.getItemCount(0); i++){
    	  int nextValue = new Double(dataset.getYValue(0, i)).intValue();
    	  if (modeValue < nextValue){
    		 modeValue = nextValue;
    		 modeIndex = (i+1);
    	  }
       }
       histogramModeIndex = new Integer(modeIndex);
       histogramModeValue = new Integer(modeValue);
   }

    /**
     * Creates a chart.
     * @param dataset  a dataset.
     * @return The chart.
     */
    private static JFreeChart createChart(IntervalXYDataset dataset) {
        JFreeChart chart = ChartFactory.createHistogram(
            title,							//title
            "Generation Solution Found",	//X-Axis Label	
            "Occurence Count",				//X-Axis Label
            dataset,						//the data
            PlotOrientation.VERTICAL,		//plot orientation
            false,							//legend?
            true,							//tooltips?
            false);							//URL
        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setDomainPannable(true);
        plot.setRangePannable(true);
        plot.setBackgroundPaint(Color.white);
        plot.setDomainGridlinePaint(Color.lightGray);
        plot.setRangeGridlinePaint(Color.lightGray);
        plot.setRangeGridlineStroke(new BasicStroke(1.0f));
        NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
        yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();
        xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        
        
        //xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); //slant axis labels by 45 degrees
        XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(true); //draw bar outlines
        renderer.setOutlineStroke(new BasicStroke(0.5f)); //these are deprecated by they work. not sure what to use in their place
        renderer.setOutlinePaint(Color.black);
        renderer.setBarPainter(new StandardXYBarPainter()); //make bars flat paint
        renderer.setShadowVisible(false); //turn off shadowing
        return chart;
       
    }
    
    public Integer getHistogramModeValue(){
    	return histogramModeValue;
    }
    
    public Integer getHistogramModeIndex(){
    	return histogramModeIndex;
    }

	/**
	 * This method initializes the indicator panel which holds the
	 * Label and text field statistics indicators and selectors
	 * @return javax.swing.JPanel containing the GUI features for this panel	
	 */
	private JPanel getIndicatorPanel() {
		if (indicatorPanel == null) {
			histBinffCallCountLabel = new JLabel("  FF Call Count Bin Avg");
			indicatorPanelSpacer1 = new JLabel("");
			indicatorPanelSpacer1.setPreferredSize(new java.awt.Dimension(40,20));
			indicatorPanelSpacer2 = new JLabel("");
			indicatorPanelSpacer2.setPreferredSize(new java.awt.Dimension(30,20));
			occurenceCountLabel = new JLabel("  Occurence Count");
			histBinNumberlabel = new JLabel("Bin Number");
			indicatorPanel = new JPanel();
			indicatorPanel.setLayout(new FlowLayout());
			indicatorPanel.setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.black,2));
			indicatorPanel.setBackground(java.awt.Color.lightGray);
			indicatorPanel.add(histBinNumberlabel, null);
			indicatorPanel.add(getBinNumber(), null);
			indicatorPanel.add(occurenceCountLabel, null);
			indicatorPanel.add(getOccurenceCountValue(), null);
			indicatorPanel.add(histBinffCallCountLabel, null);
			indicatorPanel.add(getHistBinFFCallCountField(), null);
			indicatorPanel.add(indicatorPanelSpacer2, null);
			indicatorPanel.add(getPlotButton(), null); 
			indicatorPanel.add(indicatorPanelSpacer1, null);
			indicatorPanel.add(globalGARunStatsPanel(), null);
		}
		return indicatorPanel;
	}
as per the call to dataset.addSeries("Generation Solution Found", formatHistogramData(MSO.getGenSolutionFoundVector()), 100,1,101); //(series ID, data, number of bins (granularity), lowest, highest)
my histogram has 100 bins starting from bin 1 to 101. this lines up the tickmarks and labels perfectly to the plot's gridlines at the left edge of each histogram bin. I would prefer to have the tickmarks and labels be centered on each histogram bin instead. is there a way to do this?

Gxb0514
Posts: 10
Joined: Mon Dec 02, 2013 2:30 am
antibot: No, of course not.

Re: Aligning domain axis with histogram bins

Post by Gxb0514 » Tue Dec 03, 2013 3:25 am

one more related question while I am at it. as you may notice from my previous code I am making a call to

renderer.setOutlineStroke(new BasicStroke(0.5f)); //these are deprecated by they work. not sure what to use in their place
renderer.setOutlinePaint(Color.black);

these functions are however deprecated in 1.0.16 release of jfreechart. anyone know what I should be using in their place?

John Matthews
Posts: 513
Joined: Wed Sep 12, 2007 3:18 pm

Re: Aligning domain axis with histogram bins

Post by John Matthews » Tue Dec 03, 2013 3:51 am

The API suggests setSeriesOutlineStroke() or setBaseOutlineStroke() for the deprecated method.

Gxb0514
Posts: 10
Joined: Mon Dec 02, 2013 2:30 am
antibot: No, of course not.

Re: Aligning domain axis with histogram bins

Post by Gxb0514 » Sun Dec 15, 2013 10:06 pm

HI all

I wanted to try and get some additional help with this. See figure below.

Image

can anyone suggest how I can move the tickmarks and /or the labels on the x-axis to be in the center of each of the histogram bins?

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Re: Aligning domain axis with histogram bins

Post by david.gilbert » Wed Dec 18, 2013 6:57 pm

You would have to modify a bit of code to make this happen, but in the NumberAxis class there is a method:

Code: Select all

public List refreshTicks(Graphics2D g2, AxisState state, 
            Rectangle2D dataArea, RectangleEdge edge)
The list contains instances of NumberTick which contains both a value (used to position the label) and a string (the label to display). In the code that generates the list, you need to just shift the value by 0.5, but after it has been used to generate the text label. It probably would need doing in a couple of places, since there is code for both horizontal axes and vertical axes.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

Locked