I’m trying to label each of 2 subplots with different titles. The Chart Title property places a title above the top subplot only. I would like to put a different title above the lower subplot, below the upper one.
As a work-around, I tried using a label on top of the Easy Chart (between the subplots with a gap of 50). This is a less than desirable solution, as resizing the window causes re-positioning of the text (yes, I tried anchoring, resizing, and using relative mode all to no avail).
I also scoured the hidden properties of the Easy Chart and was unable to find a property for a subplot title. Is there such a thing? If so, where is it? If not, does anyone have an acceptable solution?
Reviving a zombie, but is there a variable to use to get the “Subplot %s Title” to show the label created for the subplot, rather than a generic “Subplot 1 Title” “Subplot 2 Title” etc? I’ve been trying to understand https://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/axis/NumberAxis.html values, but not making much headway. Is there a way to insert a variable to read each Subplot label in the “for” loop?
There is no UI available way to configure a sub plot title on the easy chart. You have to do it through scripting.
@PGriffith’s script above defines a new axis with a label defined in the constructor, the ‘Subplot %s Title’ was used for simplicity and illustration, the label can be made specific for the application.
By default plot labels are Null.
If you want to retrieve the plot label after creation, you can loop through all of the plots as shown above and use getDomainAxis().getLabel(). There is also a setLabel() that you should be able to use to set the label.
See attached screenshot. I’d like to get the labels from the axis list as the title of each subplot chart. Are the subplot labels a property that can be written?
Following @PGriffith example, how could I write a different title to each subplot that uses the labels created in the easy chart configurator?
Sorry for such unclear questions, I’m new to all of this.
So, those Labels are for the Range Axis, in this case that is what is traditionally called the Y-Axis.
It is possible to Access those labels, but it is complicated by the fact that there can possibly be more than one Range Axis assigned to a sub plot, and you would need to decide how that is handled.
As an example, you could do something like the following:
from org.jfree.chart.axis import NumberAxis
from java.awt import Font
for index, plot in enumerate(chart.getPlot().getSubplots()):
title = ''
for rangeIndex in range(plot.getRangeAxisCount()):
title += plot.getRangeAxis(rangeIndex).getLabel() if len(title) == 0 else 'vs ' + plot.getRangeAxis(rangeIndex).getLabel()
labelAxis = NumberAxis(title)
labelAxis.setLabelFont(Font("Tahoma", Font.BOLD, 16))
lableAxis.setTickLabelsVisible(False)
lableAxis.setTickMarksVisible(False)
lableAxis.setAxisLineVisible(False)
plot.setDomainAxis(1, labelAxis)
Note: This is untested so might need a few tweaks, but should get you close.
Also, I shamelessly stole the code provided by @PGriffith
So I threw together something to give this a try and the code as I have it produced the results I expected, with 1 exception. We need to make sure that there are subplots defined. The only way I know to do this is to check the type of chart.getPlot() . If there are subplots in use then the type will be CombinedDomainXYPlot.
Code now looks like this:
from org.jfree.chart.axis import NumberAxis
from java.awt import Font
if chart.getPlot().getPlotType() == 'Combined_Domain_XYPlot':
for index, plot in enumerate(chart.getPlot().getSubplots()):
title = ''
for rangeIndex in range(plot.getRangeAxisCount()):
title += plot.getRangeAxis(rangeIndex).getLabel() if len(title) == 0 else ' vs ' + plot.getRangeAxis(rangeIndex).getLabel()
labelAxis = NumberAxis(title)
labelAxis.setLabelFont(Font('Tahoma',Font.BOLD, 16))
labelAxis.setTickLabelsVisible(False)
labelAxis.setTickMarksVisible(False)
labelAxis.setAxisLineVisible(False)
plot.setDomainAxis(1,labelAxis)
else:
plot = chart.getPlot()
title = ''
for rangeIndex in range(plot.getRangeAxisCount()):
title += plot.getRangeAxis(rangeIndex).getLabel() if len(title) == 0 else ' vs ' + plot.getRangeAxis(rangeIndex).getLabel()
labelAxis = NumberAxis(title)
labelAxis.setLabelFont(Font('Tahoma',Font.BOLD, 16))
labelAxis.setTickLabelsVisible(False)
labelAxis.setTickMarksVisible(False)
labelAxis.setAxisLineVisible(False)
plot.setDomainAxis(1,labelAxis)
No, because of Python's dynamic typing, you can just ask for whatever property/method you need, and it'll either exist, or throw an error.
getLabel is defined on JFreeChart's base Axis interface - Axis (JFreeChart 1.5.0 API). In the case of an XYPlot, you know that getRangeAxis returns (at least) a ValueAxis, which is a direct inheritor of Axis, so it has all the same methods: XYPlot (JFreeChart 1.5.0 API)
Learn something everyday (or at least be reminded of it).
So that makes the working code:
from org.jfree.chart.axis import NumberAxis
from java.awt import Font
plots = getattr(chart.plot,"subplots",[chart.plot])
for index, plot in enumerate(plots):
title = ''
for rangeIndex in range(plot.getRangeAxisCount()):
title += plot.getRangeAxis(rangeIndex).getLabel() if len(title) == 0 else ' vs ' + plot.getRangeAxis(rangeIndex).getLabel()
labelAxis = NumberAxis(title)
labelAxis.setLabelFont(Font('Tahoma',Font.BOLD,16))
labelAxis.setTickLabelsVisible(False)
labelAxis.setTickMarksVisible(False)
labelAxis.setAxisLineVisible(False)
plot.setDomainAxis(1,labelAxis)
I only used the Range Axis label because that is what you were looking for.
The title can be anything that you want it to be, there are even ways that you could make it dynamic.
That's why I was trying to find the different variables, to see if I could set the subplot title independent of the range axis label. I see in the easy chart configurator that there's a "Name" and "Label" columns, and the "getLabel()" function returns the contents of the label column, but I don't see anything like this for Name (at the freechart api page).
I really appreciate your patience, this is my first time doing anything in java/python.
Which is unfortunate since the range axis only gets it name from that column, it appears the Name column is just an identifier. You’ve already been a huge help!