XYDifferenceRenderer change outline color

Hi,

In Report Module, I created script below to color area between 2 lines :

Is it possible to change outlines color ? Dash pattern and width too ?

from java.awt import BasicStroke, Color
from org.jfree.chart.renderer.xy import XYDifferenceRenderer
	
renderer=XYDifferenceRenderer(Color(0, 255, 0, 127), Color(255,71,71,127), 0)
chart.getXYPlot().setRenderer(renderer)

Thanks

Can you tag your post as Vision or Perspective to help guys like me that get confused? Thanks.

Those are a flare-lit tipoff that this is not Perspective. They apply to both Vision and Reporting.

Apparently the outlines are drawn based on the Series Color so you can change it using the setSeriesPaint()

from java.awt import BasicStroke, Color
from org.jfree.chart.renderer.xy import XYDifferenceRenderer
	
renderer=XYDifferenceRenderer(Color(0, 255, 0, 127), Color(255,71,71,127), 0)
renderer.setSeriesPaint(Color.BLACK) #or whatever color you want
chart.getXYPlot().setRenderer(renderer)

For the dash pattern and width I imagin you would need to build a BasicStrok and then use rendere.setSeriesStroke(yourBasicStroke)

With my script :
Area between lines is colored but default lines colors are used

image

With your scipt @lrose :
Area not colored and lines colored with my own pens.
image

That’s what I get for just posting the code off the top of my head.

	from java.awt import BasicStroke, Color
	from org.jfree.chart.renderer.xy import XYDifferenceRenderer
	
	renderer = XYDifferenceRenderer(Color(0,255,0,127), Color(255,71,71,127),0)
	#This loop will set all of the series colors to black, the important thing is that
	#you have to specifiy the series index in the call to setSeriesPaint
	for series in range(chart.getXYPlot().getSeriesCount()):
		renderer.setSeriesPaint(series,Color.BLACK)
	
	#This code sets up a Dashed Stroke, you don't need to store them all in variables
	#like this but I wanted to be explicit so you knew what was what.
	width = 2.0
	cap = BasicStroke.CAP_BUTT
	join = BasicStroke.JOIN_BEVEL
	miterlimit = 10.0
	dashArray = [3.0,3.0]
	dashPhase = 0
	stroke = BasicStroke(width,cap,join,miterlimit,dashArray,dashPhase)
	#this sets the stroke for series 1,  series index is zero based and depends on how the dataset
	#is configured so you may need to play with the index to get what you're looking for.
	renderer.setSeriesStroke(1,stroke)

	#now set the plot's renderer 
	chart.getXYPlot().setRenderer(renderer)

The reason why my original code didn’t work is because setSeriesPaint() takes two arguments and I only provided 1, so the configureChart function was erroring resulting in the renderer not being set, so the default renderer remained.

This code I believe should demonstrate what you need to get the outcome you’re looking for.

If you want to have the stroke change based on the difference then you would have to sub class the XYDifferenceRenderer class, doable, but not exactly trivial.

4 Likes

Hi,

Thanks for your code.
Now the chart colors area under my first serie. :upside_down_face:
image

My code :

from java.awt import BasicStroke, Color
from org.jfree.chart.renderer.xy import XYDifferenceRenderer
	
renderer=XYDifferenceRenderer(Color(0, 200, 83, 127), Color(255,23,68,127), 0)
	
width = 1.0
cap = BasicStroke.CAP_BUTT
join = BasicStroke.JOIN_BEVEL
miterlimit = 10.0
dashArray = [2,5]
dashPhase = 0
stroke0 = BasicStroke(2.0)
stroke1 = BasicStroke(width,cap,join,miterlimit,dashArray,dashPhase)
	
renderer.setSeriesPaint(0,Color(0,145,234))
renderer.setSeriesPaint(1,Color(255,23,68))
renderer.setSeriesStroke(0,stroke0)
renderer.setSeriesStroke(1,stroke1)
	
chart.getXYPlot().setRenderer(renderer)

To resolve this issue we deleted manually all pens in chart properties and recreate them. We only changed key and axis attribution.
Strange :thinking:

Is it possible to change Pen Names and Axis label in my script ?

It is possible, easier to do it at dataset creation.

Do you have an example in python ? It’s for Module report.

Report module or standard chart, isn’t really applicable here. Somewhere you are generating the dataset for the chart. The best practice would be to change the names there. By default whatever the column names of the dataset are is what the Legend Item Labels will be. I would recommend doing this that way, as then it is straight forward and not hidden away in a configuration script.

However, it is possible to do this in script. You have to subclass XYSeriesLabelGenerator and then through some method provide a new label. Here I am just using a dictionary to map from the old labels to the new labels.

	from java.awt import BasicStroke, Color
	from org.jfree.chart.renderer.xy import XYDifferenceRenderer
	from org.jfree.chart.labels import XYSeriesLabelGenerator
	
	renderer=XYDifferenceRenderer(Color(0, 200, 83, 127), Color(255,23,68,127), 0)
		
	stroke0 = BasicStroke(2.0)
	stroke1 = BasicStroke(1.0,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL,10.0,[2.0,5.0],0)
		
	renderer.setSeriesPaint(0,Color(0,145,234))
	renderer.setSeriesPaint(1,Color(255,23,68))
	renderer.setSeriesStroke(0,stroke0)
	renderer.setSeriesStroke(1,stroke1)
	
	class customXYSeriesLabelGenerator(XYSeriesLabelGenerator):
		__newLabelMap = {'Old Series 0 Label':'New Series 0 Label','Old Series 1 Label':'New Series 1 Label'}
	
		def generateLabel(self,dataset,series):
			#the Series Key is the "Old Label"
			key = dataset.getSeriesKey(series)
			#insure that the key exists in the newLabelMap, if not just return the original name
			if key in self.__newLabelMap.keys():
				return self.__newLabelMap[key]
			return key
	#Create an instance of your Label Generator and set the LegendItemLabelGenerator of the renderer to use the new labels.
	renderer.setLegendItemLabelGenerator(customXYSeriesLabelGenerator())

	chart.getXYPlot().setRenderer(renderer)

Hi,
I observed color problems in few charts.
Majority are good but others are wrong like below.
How is it possible ?
Bars could be responsible of that ?
image
Normally chart below should be entirely red.
image

My script :

from java.awt import BasicStroke, Color
from org.jfree.chart.renderer.xy import XYDifferenceRenderer
	
renderer=XYDifferenceRenderer( Color(255,138,101,127),Color(129, 199, 132, 127), 0)
	
width = 1.0
cap = BasicStroke.CAP_SQUARE
join = BasicStroke.JOIN_BEVEL
miterlimit = 10.0
dashArray = [2,5]
dashPhase = 0
stroke0 = BasicStroke(2.0)
stroke1 = BasicStroke(width,cap,join,miterlimit,dashArray,dashPhase)
	
renderer.setSeriesPaint(0,Color(0,145,234))
renderer.setSeriesPaint(1,Color(255,23,68))
renderer.setSeriesStroke(0,stroke0)
renderer.setSeriesStroke(1,stroke1)
	
chart.getXYPlot().setRenderer(renderer)
	
chart.getXYPlot().getRangeAxis(0).setLabel(data['influencerTitle'])

Thanks

Well, it’s hard to say, as nothing you are doing in your script is actually controlling that behavior. That is controlled by the Renderer. You may need to look for some answers elsewhere, in relation to the Jfree Chart’s XYDifferenceRenderer.

If you remove the bars, does that change the behavior? I wouldn’t expect it to.

Without bars problem is the same.
:thinking: