I'm making a bar chart in Matplotlib with a call like this:
xs.bar(bar_lefts, bar_heights, facecolor='black', edgecolor='black')
I get a barchart that looks like this:
What I'd like is one with no white gap between consecutive bars, e.g. more like this:
Is there a way to achieve this in Matplotlib using the bar() function?
Add width=1.0 as a keyword argument to bar(). E.g.
xs.bar(bar_lefts, bar_heights, width=1.0, facecolor='black', edgecolor='black').
This will fill the bars gaps vertically.
It has been 8 years since this question was asked, and the matplotlib API now has built-in ways to produce filled, gapless bars: pyplot.step() and pyplot.stairs() with the argument fill=True.
See the docs for a fuller comparison, but the primary difference is that step() defines the step positions with N x and N y values just like plot() would, while stairs() defines the step positions with N heights and N+1 edges, like what hist() returns. It is a subtle difference, and I think both tools can create the same outputs.
Just set the width 1 over the number of bars, so:
width = 1 / len(bar_lefts)
xs.bar(bar_lefts, bar_heights, width=width, color='black')
You can set the width equal to the distance between two bars:
width = bar_lefts[-1] - bar_lefts[-2]
xs.bar(bar_lefts, bar_heights, width=width)
Related
I am drawing some graphs and I wanna import them in LaTex in 2 by 2 format. One of the problems is that values on the y-axis for one graph range from 1 to 6, but for another graph, those range from 1 to 200. Because of that, when I import graphs into my document, they do not look good. Is there any way to set the same width for value on the y-axis?
You can set the y axis limits using ax.set_ylim or plt.ylim:
# Set axis from 1 to 200
ax.set_ylim((1,200))
# Or just set it directly - this will also act on the current axis
plt.ylim((1,200))
Edit: The question is about widths rather than limits.
I think making the subplots together on one figure should solve this problem.
plt.figure()
plt.subplot(2,2,1)
plt.plot(x1,y1)
.
.
plt.subplot(2,2,4)
plt.plot(x4,y4)
I am trying to build a simple histogram. For some reason, my bars are behaving abnormally. As you can see in this picture, my bar over "3" is moved to the right side. I am not sure what caused it. I did align='mid' but it did not fix it.
This is the code that I used to create it:
def createBarChart(colName):
df[colName].hist(align='mid')
plt.title(str(colName))
RUNS = [1,2,3,4,5]
plt.xticks(RUNS)
plt.show()
for column in colName:
createBarChart(column)
And this is what I got:
bar is not centered over 3
To recreate my data:
df = pd.DataFrame(np.random.randint(1,6,size=(100, 4)), columns=list('ABCD'))
Thank you for your help!
P/s: idk if this info is relevant, but I am using seaborn-whitegrid style. I tried to recreate a plot with sample data and it's still showing up. Is it a bug?
hist created using random data
The hist function is behaving exactly as it is supposed to. By default it splits the data you pass into 10 bins, with the left edge of the first bin at the data's minimum value and the right edge of the last bin at its maximum. The chart below shows the randomly generated data binned this way, with red dashed lines to mark the edges of the bins.
The way around this is to define the bin edges yourself, with a slight adjustment to the minimum and maximum values to centre the bars over the x axis ticks. This can be done quite easily with numpy's linspace function (using column A in the randomly generated data frame as an example):
bins = np.linspace(df["A"].min() - .5, df["A"].max() + .5, 6)
df["A"].hist(bins=bins)
We ask for 6 values because we are defining the bin edges, this will result in 5 bins, as shown in this chart:
If you wanted to keep the gaps between the bars you can increase the number of bins to 9 and adjust the offset slightly, but this wouldn't work in all cases (it works here because every value is either 1, 2, 3, 4 or 5).
bins = np.linspace(df["A"].min() - .25, df["A"].max() + .25, 10)
df["A"].hist(bins=bins)
Finally, as this data contains discrete values and really you are plotting the counts, you could use the value_counts function to create a series that can then be plotted as a bar chart:
df["A"].value_counts().sort_index().plot(kind="bar")
# Provide a 'color' argument if you need all of the bars to look the same.
df["A"].value_counts().sort_index().plot(kind="bar", color="steelblue")
Try using something like this in your code to create all of the histogram bars to the same place.
plt.hist("Your data goes here", bins=range(1,7), align='left', rwidth=1, normed=True)
place your data where I put your data goes here
According to the documentation, one can set the range of the x-axis using the hist function, but there doesn't seem to be a way to control the y-axis.
I have a figure with 4 subplots, arranged in a 2x2 fashion, all of which are histograms. I have made their x-axis to be entirely the same by setting the range, but have been unable to figure out how to do likewise with the y-axis. But when I try to control the y-axis, using set_ylim, I get an error. When I tried using pylab.axis, the plots didn't turn out correctly (the bars of the historgram all had a y-value of 0.
pylab.hist(myData[x], bins = 20, range=(0,400))
pylab.axis([0,400,0,300])
How do I control the y-axis of the histogram? Essentially what I"m looking for is something like range in the hist function, but for the y-axis.
Update:
plotNumber = 1
for i in xrange(4):
pylab.subplot(2, 2, plotNumber)
pylab.hist(myData[i], bins = 20, range=(0,400))
pylab.title('Some Title')
pylab.xlabel('X')
pylab.ylabel('Y')
plotNumber += 1
pylab.show()
But when I include
pylab.axis([0,400,0,300])
All the y-values correspond to 0 (the histogram is flat).
Answer is given here: setting y-axis limit in matplotlib
axes = plt.gca()
axes.set_xlim([xmin,xmax])
axes.set_ylim([ymin,ymax])
For me this works for histogram subplots.
If you're looking to set ticks on the y-axis every n values, you can use:
pylab.yticks(range(min, max, n))
I am using Python 2.7.
When adding a bar plot, eg
an_axis.bar(xvalues, yvalues)
The default bar width is 0.8, but my plots have a variable number of bars & risk getting messed up with the width set manually.
Is there a good way to set the bar width programmatically?
OK - this seems to work:
minx, maxx = plt.getp(ax2, 'xbound')
ax2.bar(xvalues, yvalues,
width=(maxx-minx)/len(xvalues))
Which I was able to figure out after discovering:
plt.getp(object) # In this case ax2
Without additional parameters this gives a list of properties & their values; very useful for exploring matplotlib objects.
I use the following to reduce width of bars in Panda:
for container in ax.containers:
plt.setp(container, width=.25)
However, on doing this, the labels on the x-axis remain at original position, as seen below. How can I move them to correspond to new bar width. In other words, is there a function to get the x coordinate of the center of each bar?
You may want to set the width during plot(), something like this:
df.plot(kind='bar', stacked=True, width=0.25, align='center')
In the document it doesn't show you can set the width, but in fact it will take it as **kwds
It will plot with the desired width with aligned x-axis labels.