23

I'm plotting about 10,000 items in an array. They are of around 1,000 unique values.

The plotting has been running half an hour now. I made sure rest of the code works.

Is it that slow? This is my first time plotting histograms with pyplot.

3
  • Yes, I would say that is very slow. In reality it depends on how many bins you selected, but i.e. for a 1000 bins I can plot 10 000 random generated values in about a second or two. Python 2, laptop core Intel i5 os Ubuntu 14.04. Show some code, it'll make things easier. Commented Mar 2, 2016 at 4:45
  • 1
    Actually I solved it by just reducing number of bins. Thanks though. Commented Mar 2, 2016 at 4:50
  • 1
    Are you sure you're using the correct column data type? I was using strings instead of integers and that was a sheer error on my part. Commented Aug 1, 2019 at 8:57

10 Answers 10

31

To plot histograms using matplotlib quickly you need to pass the histtype='step' argument to pyplot.hist. For example:

plt.hist(np.random.exponential(size=1000000,bins=10000))
plt.show()

takes ~15 seconds to draw and roughly 5-10 seconds to update when you pan or zoom.

In contrast, plotting with histtype='step':

plt.hist(np.random.exponential(size=1000000),bins=10000,histtype='step')
plt.show()

plots almost immediately and can be panned and zoomed with no delay.

Sign up to request clarification or add additional context in comments.

2 Comments

This is much faster as you say (I'm seeing the same times as you). But the graphs look very different with histtype='step'.
@dementedhedgehog yes, they do. I guess it depends on which discipline you are in. In high energy physics the step style is the norm. I opened an issue on the matplotlib page to discuss the issue here a while ago: github.com/matplotlib/matplotlib/issues/7121.
19

It will be instant to plot the histogram after flattening the numpy array. Try the below demo code:

import numpy as np

array2d = np.random.random_sample((512,512))*100
plt.hist(array2d.flatten())
plt.hist(array2d.flatten(), bins=1000)

5 Comments

Was having this same issue, this solution worked like a charm.
This should be the accepted answer. Handled 100k values instantly as opposed to it not returning otherwise. If plotting multiple histograms, array2d.flatten() does cause the histograms to be plotted as one. Resolution is to add each column separately.
This should the accepted answer. Far, far superior to the ones more upvoted
This is fantastic! But I wonder why flattening the array would have such a huge improvement in executing time like that?
It's very weird that this works considering that Matplotlib uses numpy.histogram underneath hist, which already calculates the histogram with the array flattened.
7

Importing seaborn somewhere in the code may cause pyplot.hist to take a really long time.

If the problem is seaborn, it can be solved by resetting the matplotlib settings:

import seaborn as sns
sns.reset_orig()

Comments

3

For me, the problem is that the data type of pd.Series, say S, is 'object' rather than 'float64'. After I use S = np.float64(S), then plt.hist(S) is very quick.

1 Comment

The correct way to change the type of a pandas.Series is with .astype(): S.astype('float64')
2

Since several answers already mention the issue of slowness with pandas.hist(), note that it may be due to dealing with non-numerical data. An issue easily solved by using value_counts() :

df['colour'].value_counts().plot(kind='bar')

credits

Comments

1

I was facing the same problem using Pandas .hist() method. For me the solution was:

pd.to_numeric(df['your_data']).hist()

Which worked instantly.

Comments

0

For me it took calling figure.canvas.draw() after the call to hist to update immediately, i.e. hist was actually fast (discovered that after timing it), but there was a delay of a few seconds before figure was updated. I was calling hist inside a matplotlib callback in a jupyter lab cell (qt5 backend).

Comments

0

Anyone running into the issue I had - (which is totally my bad :) )

If you're dealing with numbers, make sure when reading from CSV that your datatype is int/float, and not string.

values_arr = .... .flatten().astype('float')

Comments

0

If you are working with pandas, make sure the data you passed in plt.hist() is a 1-d series rather than a dataframe. This helped me out.

Comments

0

For my PyCharm on Windows Machine, putting the following snippet of code, before the histplot call (sns) in my case, worked:

import matplotlib
import matplotlib.pyplot as plt
matplotlib.use('Qt5Agg')

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.