plotly / plotly.py

The interactive graphing library for Python :sparkles: This project now includes Plotly Express!
https://plotly.com/python/
MIT License
15.66k stars 2.51k forks source link

Tick texts on the histogram are shifted to the left if "xbins" and "tickvals" were customized #3780

Open PlatonB opened 2 years ago

PlatonB commented 2 years ago

Let's build a histogram for 1000 random values from 0 to 1, narrow down the bins and add tick text to each bin. To make the existence of the bug visible, draw a vertical line in the middle of each bin.

import sys
sys.dont_write_bytecode = True
import numpy as np
import pandas as pd
import plotly.express as px

df = pd.DataFrame({'rand_vals': np.random.rand(1, 1000)[0]}).round(4)
hist = px.histogram(df)
hist.update_traces(xbins={'start': df['rand_vals'].min(),
                          'size': 0.01})
ranges = [[round(val, 4),
           round(val + 0.0099, 4)] for val in np.arange(df['rand_vals'].min(),
                                                        df['rand_vals'].max() + 0.01, 0.01)]
hist.update_xaxes(tickvals=[np.mean(rng) for rng in ranges],
                  ticktext=[' - '.join(map(str, rng)) for rng in ranges],
                  tickfont_size=10,
                  rangemode='tozero')
for rng in ranges:
        hist.add_vline(np.mean(rng),
                       line_width=1,
                       line_dash='dash')
hist.show()

Result: plotly_ticktext_shift_1

An interesting detail: if I double zoom the diagram (HTML), the offset eliminates: plotly_ticktext_shift_2

If anyone thinks the problem is because the tick texts are too long, let's simplify them by removing ticktext=[' - '.join(map(str, rng)) for rng in ranges],. The displacement will remain: plotly_ticktext_shift_3

alexcjohnson commented 2 years ago

@PlatonB can you clarify the problem here? Looks to me as though when the labels are vertical they're perhaps 1-2 px to the left of where they should be, is that what you mean?

PlatonB commented 2 years ago

@alexcjohnson I don't know how to measure the exact number of px, but it is clearly visible that the labels are to the left. If I zoom in the canvas, the labels return to the center (where they should be).