Histogram bar alignments seem to be imprecise
toninagy opened this issue · comments
plot.hist().add(measurements).rwidth(0.1).bins(4).stacked(false).align(HistBuilder.Align.mid).orientation(HistBuilder.Orientation.vertical);
plot.xlim(1,2);
plot.title("First run");
plot.show();
This alignment is imprecise, e.g. if I zoom in on the plot, I've got a bar on 1.09, 1.29, 1.47 and 1.66 whereas the measurements list includes the double values of 1.0, 1.25, 1.5, 1.75.
If I adjust the HistBuilder.Align from mid to left, only the bar above 1.0 will be placed correctly, the others are off by a few decimal points. If I set it the Align property to right, then the other end will be precisely placed. But either way, I can't seem to make this work so that all bars are placed precisely.
Hi @toninagy
First of all, the behavior is actually derived from the original matplotlib
instead of matplotlib4j
. In fact, you must see the translated python code when you run this code.
@Test
public void testOriginal() throws IOException, PythonExecutionException {
Plot plt = new PlotImpl(DRY_RUN);
List<Double> x = Lists.newArrayList(1.0, 1.25, 1.5, 1.75);
plt.hist().add(x).rwidth(0.1).bins(4).stacked(false).align(HistBuilder.Align.mid).orientation(HistBuilder.Orientation.vertical);
plt.xlim(1,2);
plt.title("Original");
plt.show();
}
DEBUG - .plot command: ret_a985458e_a3a8_4f2f_92ef_277545c853c4 = plt.hist([[1.0, 1.25, 1.5, 1.75]],rwidth=0.1,bins=4,orientation="vertical",stacked=False,align="mid")
DEBUG - .plot command: plt.xlim(1,2)
DEBUG - .plot command: plt.title("Original")
On that condition, I can answer how to do workaround. Actually when you specify .bin(4)
, it just orders the values split into 4 bins, but not decide the positions. To decide the bin edge position, you can use .bin(list). For your case, this is the complete code to fix.
@Test
public void testFixed() throws IOException, PythonExecutionException {
Plot plt = new PlotImpl(DRY_RUN);
List<Double> x = Lists.newArrayList(1.0, 1.25, 1.5, 1.75);
List<Double> bin = Lists.newArrayList(1.0, 1.25, 1.5, 1.75, 2.0);
plt.hist().add(x).rwidth(0.1).bins(bin).stacked(false).align(HistBuilder.Align.left).orientation(HistBuilder.Orientation.vertical);
plt.xlim(1,2);
plt.title("Fixed");
plt.show();
}
This must be interesting for you to see how to handle the hist
function: https://stackoverflow.com/questions/27083051/matplotlib-xticks-not-lining-up-with-histogram
Thank you so much, I appreciate your answer and your work!
Cheers