Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jFreeChart contour plot rendering incorrectly #2

Open
kindlychung opened this issue Feb 11, 2016 · 0 comments
Open

jFreeChart contour plot rendering incorrectly #2

kindlychung opened this issue Feb 11, 2016 · 0 comments

Comments

@kindlychung
Copy link

Also posted on SO: http://stackoverflow.com/questions/35344107/jfreechart-contour-plot-rendering-incorrectly

Code:

package vu.co.kaiyin.sfreechart.plots

import java.awt.{Shape, Stroke, RenderingHints}
import javax.swing.JFrame

import org.jfree.chart.plot.{PlotOrientation, XYPlot}
import org.jfree.chart.{ChartFactory => cf}
import org.jfree.chart.renderer.GrayPaintScale
import org.jfree.chart.renderer.xy.XYBlockRenderer
import org.jfree.chart.title.PaintScaleLegend
import org.jfree.chart._
import org.jfree.chart.axis.{AxisLocation, NumberAxis}
import org.jfree.data.Range
import org.jfree.data.general.DatasetUtilities
import org.jfree.data.statistics.HistogramDataset
import org.jfree.data.xy.{IntervalXYDataset, XYZDataset}
import org.jfree.ui.{RectangleEdge, RectangleInsets}
import vu.co.kaiyin.sfreechart.{ColorPaintScale, ExtendedFastScatterPlot}
import vu.co.kaiyin.sfreechart.implicits._
import scala.util.Random.nextGaussian

/**
  * Created by kaiyin on 2/10/16.
  */
object Plots {


  def histogram(
                 dataset: IntervalXYDataset,
                 title: String = "Histogram",
                 xAxisLabel: String = "Intervals",
                 yAxisLabel: String = "Count",
                 orientation: PlotOrientation = PlotOrientation.VERTICAL,
                 legend: Boolean = true,
                 tooltips: Boolean = true,
                 urls: Boolean = true,
                 alpha: Float = 0.5F,
                 pannable: Boolean = false
               ): JFreeChart = {
    val hist = cf.createHistogram(
      title, xAxisLabel, yAxisLabel, dataset, orientation, legend, tooltips, urls
    )
    val xyPlot = hist.getPlot.asInstanceOf[XYPlot]
    if (pannable) {
      xyPlot.setDomainPannable(true)
      xyPlot.setRangePannable(true)
    }
    xyPlot.setForegroundAlpha(alpha)
    hist
  }

  def controuPlot(dataset: XYZDataset, title: String = "Contour plot", scaleTitle: String = "Scale"): JFreeChart = {
    val xAxis = new NumberAxis("x")
    val yAxis = new NumberAxis("y")
    val blockRenderer = new XYBlockRenderer
    val zBounds: Range = DatasetUtilities.findZBounds(dataset)
    println(zBounds.getLowerBound, zBounds.getUpperBound)
    val paintScale = new ColorPaintScale(zBounds.getLowerBound, zBounds.getUpperBound)
    blockRenderer.setPaintScale(paintScale)
    val xyPlot = new XYPlot(dataset, xAxis, yAxis, blockRenderer)
    xyPlot.setAxisOffset(new RectangleInsets(1D, 1D, 1D, 1D))
    xyPlot.setDomainPannable(true)
    xyPlot.setRangePannable(true)
    val chart = new JFreeChart(title, xyPlot)
    chart.removeLegend()
    val scaleAxis = new NumberAxis(scaleTitle)
    val paintScaleLegend = new PaintScaleLegend(paintScale, scaleAxis)
    paintScaleLegend.setAxisLocation(AxisLocation.BOTTOM_OR_LEFT)
    paintScaleLegend.setPosition(RectangleEdge.BOTTOM)
    chart.addSubtitle(paintScaleLegend)
    chart
  }


  def fastScatter(data: Array[Array[Float]], title: String = "Scatter plot", pointSize: Int = 5, pointAlpha: Float = 0.3F): JFreeChart = {
    val xAxis = new NumberAxis("x")
    val yAxis = new NumberAxis("y")
    xAxis.setAutoRangeIncludesZero(false)
    yAxis.setAutoRangeIncludesZero(false)
    val fsPlot = new ExtendedFastScatterPlot(data, xAxis, yAxis, pointSize, pointAlpha)
    fsPlot.setDomainPannable(true)
    fsPlot.setRangePannable(true)
    val chart = new JFreeChart(title, fsPlot)
    chart.getRenderingHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
    chart
  }

  def main(args: Array[String]) {
    //    fastScatter(Array(Array(1.0F, 2.0F, 3.0F), Array(1.0F, 2.0F, 3.0F))).vis()
    val x = (1 to 10000).map(_.toFloat).toArray
    val y = x.map(i => i * nextGaussian().toFloat * 3F).toArray
    fastScatter(Array(x, y)).vis()
    val x1 = (-13.0 to 13.0 by 0.2).toArray
    val y1 = (-13.0 to 13.0 by 0.2).toArray
    val xyzData = (for {
      i <- x1
      j <- y1
      if i > j
    } yield Array(i, j, math.sin(i) + math.cos(j))).transpose
    controuPlot(xyzData.toXYZDataset()).vis()
    histogram((1 to 10000).map(_ => nextGaussian()).toArray.toHistogramDataset()).vis()
  }
}

Full project can be found here: https://github.com/kindlychung/sfreechart

Running the above code will give you this:

enter image description here

If you look carefully, you will find a narrow band of pixels along the diagonal edge that doesn't quite fit (this is a contour plot of sin(x) + cos(y)), as if there was a tear and shift. But if I comment out the if i < j line, then the plot looks normal:

enter image description here

What went wrong and how can this be solved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant