Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Bug]: bar() displays gaps when plotting too many values #27816

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

Closed
ivanightingale opened this issue Feb 23, 2024 · 2 comments
Closed

[Bug]: bar() displays gaps when plotting too many values #27816

ivanightingale opened this issue Feb 23, 2024 · 2 comments

Comments

@ivanightingale
Copy link

ivanightingale commented Feb 23, 2024

Bug summary

When plotting around 1300-1400 values with matplotlib.pyplot.bar(), empty gaps appear in the resulting bar plot. When saving the figure, the gaps shift to a different location. If a long enough title is added to the plot, the gaps also shift.

Code for reproduction

a = np.random.rand(1355)  # one of the most apparent examples
plt.bar(range(len(a)), a)
# plt.title("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT")  # this will result in different gaps

Actual outcome

image
image

Expected outcome

Bar charts should be plotted correctly. Adding a title or saving the figure should not alter the chart.

Additional information

No response

Operating system

RHEL

Matplotlib Version

3.7.1

Matplotlib Backend

module://matplotlib_inline.backend_inline

Python version

3.10.11

Jupyter version

6.5.4

Installation

conda

@ksunden
Copy link
Member

ksunden commented Feb 23, 2024

There are simply too many bars here for the resolution of your plot. each bar is less than one pixel wide, so some bars are just missing being seen in any pixel.

By default we produce a 640x480 100 dpi image. Even if your figure had no border, each bar would be less than half a pixel wide. You can improve things by increasing the dpi (or fig size... basically just need more pixels. However, you will still see effects of the discritization even up to quite high dpis (at 1000 dpi, obviously I didnt count to see whether or not bars are missing, though I think they are all present since each bar is 2-3 pixels, but there are still some bars that are directly adjacent and some that have a 1 pixel gap between them)

One solution would be to use a vector format (e.g. svg, pdf), but that only kicks the can down the road, eventually to display it needs to be rasterized. some vector viewers may incorporate antialiasing to hide the gaps by displaying averaged pixels (we do similar things for some cases such as images, but not here), but if you are viewing something with fewer pixels allocated to it than data points, some compromises will be made.

Basically the question becomes "is a bar plot actually an effective way of communicating the information?" and I'd argue that in general if you have 1000s of points, some amount of data reduction is basically necessary. That could be things like box or violin for a single variable as here. you can even configure those to highlight outlier values so if individual points are interesting those are communicated. "data reduction" can also mean binning, e.g. summing/averaging the values in sets of 50 or 100 or whatever makes sense for what you are communicating. this makes fewer bars but ones which can be individually visible. Such binning can be done using hist

There are any other number of additional ways to reduce the data to a representable set, what makes sense for your data is very context dependent, so I cannot say. (Especially on a np.random test variable, but domain knowledge is important context too, so even just knowing what it is would likely not be enough)

There is really nothing to be done here, this is a fundamental limit of rasterized plotting. Thus I'll close this. Thank you for reporting.

@ksunden ksunden closed this as completed Feb 23, 2024
@tacaswell
Copy link
Member

When bars are significantly narrower than your pixel they can disappear. Your options are:

  • set an edge color which is sized in output space so your bars will have a minimum visible size, but it means that bars are going to overlap
  • us a vector format (e.g. svg), but that leaves you at the mercy of the browser / viewer and how it renders things that are too small
  • turn of pixel snapping
  • save at a high enough dpi where your bars are bigger than an output pixel
  • switch to using step or stairs which draws a single line rather than many rectangles (and will also have better render performance)

xref #27816
#13909

@ivanightingale ivanightingale changed the title [Bug]: bar() displays gaps when plotting around 1300 values [Bug]: bar() displays gaps when plotting too many values Feb 23, 2024
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

3 participants