How to add numbers to top of histogram bars? - python-3.x

I want to add the frequency number above each bar and want to keep the bars separated. I can't figure out how to keep the bars separated.
My code is:
df_dm2["resolution"].plot(kind='hist', color='blue', edgecolor='black', linewidth=1.2 )
plt.ylabel('Frequency')
plt.xlabel('Resolution (m)')
plt.title('Region DM2 Frame Resolution Frequency')
#plt.text( .92, 3.5, r'$\mu=1.092531 ,\ \sigma=0.091098$')
#plt.xticks(np.arange(0, 2, 0.2))
plt.yticks(np.arange(0, 200,25))
plt.savefig('histogram_dm2.png',dpi=72, bbox_inches='tight')
plt.show()
My output thus far is as follows: enter image description here

Use the rwidth option in plot:
df_dm2["resolution"].plot(kind='hist',
color='blue',
edgecolor='black',
linewidth=1.2,
rwidth=0.75)

Related

How to reduce the font size of xticks of a mosaic plot in Python

I need to reduce the font size of yticks and remove the white vertical lines plotting down from the yticks. For how much I try, it's only the xticks that get changed. Any leads would be much appreciated.
Code
fig, ax = plt.subplots(1, 1, figsize=(5, 5))
plt.subplots_adjust(left=0.1, right=0.8, top=0.8, bottom=0.1)
plt.xticks(fontsize=6)
plt.yticks(fontsize=6)
plt.rcParams['font.size'] = 6
plt.rcParams['text.color'] = 'black'
plt.rcParams["legend.facecolor"] = '#c2b6b6'
plt.rc('axes', titlesize=7)
plt.legend(handles=handles, bbox_to_anchor=(1.2, 0.9), loc='upper right', borderaxespad=0.,
fontsize=6)
mosaic(data, label_rotation=0, title=name, horizontal=False, properties=props,
labelizer=labelizer, ax=ax)
plt.savefig("tile_plot.png")
Mosaic Plot

Increasing plot size with multiple plots?

I am trying to plot a histogram with my data.
Using python on Jupyter notebook
viz = cdf[['GyrNative', 'GyMutant', 'Hbond_native', 'HMutant', 'RMSDNative','RMSDMutant', 'RMSFNative', 'RMSFMutant', 'SASANative', 'SASAMutant']]
plt.figure(figsize = (15,10))
viz.hist(grid=True, rwidth = 0.9, color ='red')
plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=0.1)
plt.show()
The plot generated are really tiny... How may I increase the size of each plot at once?
Following from the comments, if you just want to make the whole thing bigger, you should just add figsize to this and rearrange your plt. calls:
plt.tight_layout(pad=0.9, w_pad=0.5, h_pad=0.1)
viz.hist(grid=True, rwidth = 0.9, color ='red', figsize=(15,10))
plt.show()

matplotlib: controlling position of y axis label with multiple twinx subplots

I wrote a Python script based on matplotlib that generates curves based on a common timeline. The number of curves sharing the same x axis in my plot can vary from 1 to 6 depending on user options.
Each of the data plotted use different y scales and require a different axis for drawing. As a result, I may need to draw up to 5 different Y axes on the right of my plot. I found the way in some other post to offset the position of the axes as I add new ones, but I still have two issues:
How to control the position of the multiple axes so that the tick labels don't overlap?
How to control the position of each axis label so that it is placed vertically at the bottom of each axis? And how to preserve this alignment as the display window is resized, zoomed-in etc...
I probably need to write some code that will first query the position of the axis and then a directive that will place the label relative to that position but I really have no idea how to do that.
I cannot share my entire code because it is too big, but I derived it from the code in this example. I modified that example by adding one extra plot and one extra axis to more closely match what intend to do in my script.
import matplotlib.pyplot as plt
def make_patch_spines_invisible(ax):
ax.set_frame_on(True)
ax.patch.set_visible(False)
for sp in ax.spines.values():
sp.set_visible(False)
fig, host = plt.subplots()
fig.subplots_adjust(right=0.75)
par1 = host.twinx()
par2 = host.twinx()
par3 = host.twinx()
# Offset the right spine of par2. The ticks and label have already been
# placed on the right by twinx above.
par2.spines["right"].set_position(("axes", 1.2))
# Having been created by twinx, par2 has its frame off, so the line of its
# detached spine is invisible. First, activate the frame but make the patch
# and spines invisible.
make_patch_spines_invisible(par2)
# Second, show the right spine.
par2.spines["right"].set_visible(True)
par3.spines["right"].set_position(("axes", 1.4))
make_patch_spines_invisible(par3)
par3.spines["right"].set_visible(True)
p1, = host.plot([0, 1, 2], [0, 1, 2], "b-", label="Density")
p2, = par1.plot([0, 1, 2], [0, 3, 2], "r-", label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], "g-", label="Velocity")
p4, = par3.plot([0,0.5,1,1.44,2],[100, 102, 104, 108, 110], "m-", label="Acceleration")
host.set_xlim(0, 2)
host.set_ylim(0, 2)
par1.set_ylim(0, 4)
par2.set_ylim(1, 65)
host.set_xlabel("Distance")
host.set_ylabel("Density")
par1.set_ylabel("Temperature")
par2.set_ylabel("Velocity")
par3.set_ylabel("Acceleration")
host.yaxis.label.set_color(p1.get_color())
par1.yaxis.label.set_color(p2.get_color())
par2.yaxis.label.set_color(p3.get_color())
par3.yaxis.label.set_color(p4.get_color())
tkw = dict(size=4, width=1.5)
host.tick_params(axis='y', colors=p1.get_color(), **tkw)
par1.tick_params(axis='y', colors=p2.get_color(), **tkw)
par2.tick_params(axis='y', colors=p3.get_color(), **tkw)
par3.tick_params(axis='y', colors=p4.get_color(), **tkw)
host.tick_params(axis='x', **tkw)
lines = [p1, p2, p3, p4]
host.legend(lines, [l.get_label() for l in lines])
# fourth y axis is not shown unless I add this line
plt.tight_layout()
plt.show()
When I run this, I obtain the following plot:
output from above script
In this image, question 2 above means that I would want the y-axis labels 'Temperature', 'Velocity', 'Acceleration' to be drawn directly below each of the corresponding axis.
Thanks in advance for any help.
Regards,
L.
What worked for me was ImportanceOfBeingErnest's suggestion of using text (with a line like
host.text(1.2, 0, "Velocity" , ha="left", va="top", rotation=90,
transform=host.transAxes))
instead of trying to control the label position.

Set matplotlib legend markersize to a constant

I'm making a diagram using matplotlib, and it has plt.Circles and plt.axvlines to represent different shapes. I need a legend to describe these shapes, but the problem is the legend marker (the image part), changes size depending on the input, which looks awful. How do I set the size to a constant?
fig = plt.figure(figsize=(6.4, 6), dpi=200, frameon=False)
ax = fig.gca()
# 3 Circles, they produce different sized legend markers
ax.add_patch(plt.Circle((0,0), radius=1, alpha=0.9, zorder=0, label="Circle"))
ax.add_patch(plt.Circle((-1,0), radius=0.05, color="y", label="Point on Circle"))
ax.add_patch(plt.Circle((1, 0), radius=0.05, color="k", label="Opposite Point on Circle"))
# A vertical line which produces a huge legend marker
ax.axvline(0, ymin=0.5-0.313, ymax=0.5+0.313, linewidth=12, zorder=1, c="g", label="Vertical Line")
ax.legend(loc=2)
ax.set_xlim(-2,1.2) # The figsize and limits are meant to preserve the circle's shape
ax.set_ylim(-1.5, 1.5)
fig.show()
I've seen solutions including legend.legendHandles[0]._size or various assortments of that, and it doesn't seem to change the size regardless of the value I set
The legend markers for the circles are different in size because the first circle has no edgecolor, while the two other ones have an edgecolor set via color. You may instead set the facecolor of the circle. Alternatively, you can set the linewidth of all 3 circles equal.
The legend marker for the line is so huge because it simply copies the attribute from the line in the plot. If you want to use a different linewidth, you can update it via the respective legend handler.
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerLine2D
def update_prop(handle, orig):
handle.update_from(orig)
handle.set_linewidth(2)
fig, ax = plt.subplots(figsize=(6.4, 6), dpi=200, frameon=False)
# 3 Circles, set the facecolor instead of edge- and face-color
ax.add_patch(plt.Circle((0,0), radius=1, alpha=0.9, zorder=0, label="Circle"))
ax.add_patch(plt.Circle((-1,0), radius=0.05, facecolor="y", label="Point on Circle"))
ax.add_patch(plt.Circle((1, 0), radius=0.05, facecolor="k", label="Opposite Point on Circle"))
# Line, update the linewidth via
ax.axvline(0, ymin=0.5-0.313, ymax=0.5+0.313, linewidth=12, zorder=1, c="g", label="Vertical Line")
ax.legend(loc=2, handler_map={plt.Line2D:HandlerLine2D(update_func=update_prop)})
ax.set_xlim(-2,1.2)
ax.set_ylim(-1.5, 1.5)
plt.show()

Adding a second label to colorbar

I have an imshow plot with a colorbar. I want two labels in the colorbar, one on the left side and the other one on the right side.
This is the mve:
V = np.array([[1, 2, 3], [4, 5, 6]]) # Just a sample array
plt.imshow(V, cmap = "hot", interpolation = 'none')
clb = plt.colorbar()
clb.set_label("Firstlabel", fontsize=10, labelpad=-40, y=0.5, rotation=90)
#clb.set_label("SECONDLABEL") # This is the label I want to add
plt.savefig("Example")
This produces:
I want a second label on the right side of the colorbar. If I use the commented line a second colorbar is added to my plot, and that is not what I want. How can I do this?
You can't have two label objects, but you could add a second label using clb.ax.text.
Also, note that to move the first label to the left hand side, you could use clb.ax.yaxis.set_label_position('left') rather than labelpad=-40
So, using lines:
clb = plt.colorbar()
clb.set_label("Firstlabel", fontsize=10, y=0.5, rotation=90)
clb.ax.yaxis.set_label_position('left')
clb.ax.text(2.5, 0.5, "SECONDLABEL", fontsize=10, rotation=90, va='center')
Produces this figure:

Resources