changing the spacing between tick labels on Matplotlib Heatmap - matplotlib

I am using the following code to generate this heatmap:
h= np.vstack((aug2014, sep2014,oct2014, nov2014, dec2014, jan2015, feb2015, mar2015, apr2015, may2015, jun2015, jul2015, aug2015))
dim = np.arange(1, 32, 1)
fig, ax = plt.subplots(figsize=(9,3))
heatmap = ax.imshow(h, cmap=plt.cm.get_cmap('Blues', 4), aspect=0.5, clim=[1,144])
cbar = fig.colorbar(heatmap, ticks = [1, 36, 72, 108, 144], label = 'Number of valid records per day')
ax.set_xlabel("Days", fontsize=15)
ax.set_ylabel("Months", fontsize=15)
ax.set_title("Number of valid records per day", fontsize=20)
ax.set_xticks(range(0,31))
ax.set_xticklabels(dim, rotation=45, ha='center', minor=False)
ax.set_yticks(range(0,13,1))
ax.set_yticklabels(ylabel[7:20])
ax.grid(which = 'minor', color = 'w')
ax.set_facecolor('gray')
fig.show()
As you can see, the labels on the y-axis are not very readable. I was wondering whether there would be a way for me to either increase the dimension of the grid cell or change the scale on the axis to increase the space between the labels. I have tried changing the figsize but all it did was to make the colorbar much bigger than the heatmap. I also have have two subsidiary questions:
Can someone explain to me why the grid lines do not show on the figure although I have defined them?
How can I increase the font of the colorbar title?
Any help would be welcomed!

Related

Matplotlib subplots size bigger than figure size

I discovered Matplotlib and I have a rendering problem. The 5 subplot I create step on each other, the xaxis labels and titles are behind the other plot.
Here is a part of the code I use :
fig, axs = plt.subplots(5,figsize=(8,25))
axs[0].plot(array_system_index, array_system_value, label="System", color="red", linewidth=1)
axs[0].set(xlabel="time", ylabel="Latency (µs)", yscale="log", title="System")
axs[0].axis([0, len(array_system_value), 1, 10000])
axs[1].plot(array_core0_index, array_core0_value, label="core 0", color="green", linewidth=1)
axs[1].set(xlabel="Time", ylabel="Latency (µs)", yscale="log", title="Core1")
axs[1].axis([0, len(array_core0_value), 1, 10000])
...
fig.tight_layout()
plt.show()
# fig.set_size_inches((15, 8), forward=False) # Break the png file
fig.savefig("my_graph.png", dpi=500)
Here is the result :
Graph
Do you know how can I increase the size of the figure itself ?
I tried to it after the subplot but it doesn't work and break the saved .png.

Problem with Removing Vertical Lines using tricontour

I am plotting zero-level contours using tricontour (do not want to have to triangulate data) and I am having trouble with getting rid of the vertical lines that occur when the y data goes to the next column of my grid and the sign of my z-value changes. I have tried using mask, nan, and removing the data points for which this occurs, with no luck.
Here is the code that I am using
plt.title(case+ r" case: $\alpha={}$ - Zero-level Contour Plots of Re$(|M(\gamma)|)$ and Im$|M(\gamma)|$".format(alp_val), fontsize = 16)
plt.tricontour(xx,yy,redett, levels=[0], colors='red')
plt.tricontour(xx,yy,imdett, levels=[0], colors = 'blue', linestyles='dashed')
plt.xlabel(r"x", fontsize=24)
plt.ylabel(r"$y$", fontsize=24)
plt.legend(custom_lines, [r"Re$(|M(\gamma)|)$", r"Im$(|M(\gamma)|)$"])
plt.scatter(0,0, s = 45, color='white', edgecolor='black', label =r'Simple Eigenvalue $\gamma=0$')
plt.scatter(zeroes,np.zeros(len(zeroes)), s = 45, color = 'green', edgecolor='black', label = r'Zero of $\mathcal{E}(\gamma)$')
plt.grid()
plt.show()
Want to remove vertical lines on this

matplotlib asymmetric errorbar showing wrong information

I am trying to plot a grouped barplot with asymmetrical errobars. When the error bars a symmetrical, it's producing the correct chart. However, for the asymmetric version, the length of the error bar is wrong.
Here is a minimally reproducible code:
# test with code from documentation
men_means, men_std = (20, 35, 30, 35, 27), (2, 3, 4, 1, 2)
women_means, women_std = (25, 32, 34, 20, 25), (3, 5, 2, 3, 3)
# dummy dataframe similar to what I will be using
avg = [20, 35, 30, 35, 27]
men_std_l = [19,33,28,34,25]
men_std_u = [22,37,31,39,29]
df = pd.DataFrame({'avg' :avg, 'low':men_std_l, 'high':men_std_u})
ind = np.arange(df.shape[0]) # the x locations for the groups
width = 0.35 # the width of the bars
fig, ax = plt.subplots()
rects1 = ax.bar(ind - width/2, df['avg'], width, yerr=[df['low'].values,df['high'].values], label='Men')
rects2 = ax.bar(ind + width/2, women_means, width, yerr=women_std,label='Women')
# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_title('error bar is wrong for asymmetrical, correct otherwise')
ax.legend()
fig.tight_layout()
plt.show()
I have tried the solutions from Asymmetrical errorbar with pandas (getting ValueError: In safezip, len(args[0])=5 but len(args1)=1) and plotting asymmetric errorbars using matplotlib (getting TypeError: Cannot cast array data from dtype('< U1') to dtype('float64') according to the rule 'safe')
Any help is much appreciated.
Answering my own question as I could not understand from the documentation what those lower and upper bounds of errors were. In the hindsight, it should have been clearer if I were not so used to with ggplot in r.
The matplotlib version of asymmetrical errorbar requires the the values to add and subtract from the height of the bars. It does not want the user to provide the upper and lower values, rather the numbers that should be added and subtracted. Therefore, I needed the following:
xel = df['avg'].values - df['low'].values
xeh = df['high'].values - df['avg'].values

Matplotlib: Assign legend to different figures

Inside a loop I am calculating some things and then I want to plot them in two different figures. I have set up the figures as
susc_comp, (ax1,ax2) = plt.subplots( 2, 1, sharex=True, sharey='none', figsize=(8.3,11.7))
cole_cole, (ax3) = plt.subplots( 1, 1, sharex='none', sharey='none', figsize=(8.3,11.7))
for j,temp in enumerate(indexes_T[i]):
Calculate and plot in the corresponding ax1,ax2,ax3
plt.legend(loc=0, fontsize='small', numpoints = 1, ncol=(len(indexes_T[i]))/2, frameon=False)
susc_comp.savefig('suscp_components'+str(field)+'Oe.png', dpi=300)
cole_cole.savefig('Cole_Cole'+str(field)+'Oe.png', dpi=300)
But I get the legend only in the sus_comp figure (it is the same legend for both figures). How can I select the figure and add the legend to each of them?
Thank you very much!
You can call figure.legend directly (although I think this may have less functionality than plt.legend). Therefore, I would do this a different way.
The question states that both legends are the same. In addition, the second figure only has 1 axes in it. Therefore one solution would be to get the handles and labels from ax3, then manually apply those to both figures. A simplified example is below:
import matplotlib.pyplot as plt
susc_comp, (ax1, ax2) = plt.subplots(1,2)
cole_cole, ax3 = plt.subplots()
ax1.plot([1,2,3], label="Test1")
ax2.plot([3,2,1], label="Test2")
ax3.plot([1,2,3], label="Test1")
ax3.plot([3,2,1], label="Test2")
handles, labels = ax3.get_legend_handles_labels()
ax2.legend(handles, labels, loc=1, fontsize='small', numpoints = 1)
ax3.legend(handles, labels, loc=1, fontsize='small', numpoints = 1)
plt.show()
This gives the following 2 figures:

multiple markers in legend

My script for plotting creates two legends for each label. I do not know how to make legend() not duplicate. I checked on stackoverflow and found two methods. But I could not implement them here. Any ideas?
Matplotlib: Don't show errorbars in legend
Stop matplotlib repeating labels in legend
symbols = [u'\u2193']
#Plotting our vsini values
for i, symbol in enumerate(symbols):
for x0,y0 in zip(vsini_slit_cl, vsini_slit):
plt.text(x0,y0, symbol, fontname='STIXGeneral', size = 10, va='center', ha='center', clip_on=True,color = '#737373')
for i, symbol in enumerate(symbols):
for x0, y0 in zip(vsini_cl_sl, vsini_sl):
plt.text(x0, y0, symbol, fontname='STIXGeneral', size = 10, va='center', ha='center', clip_on=True)
# PLOTTING VSINI FROM LITERATURE
plt.plot((vmag_lit-jmag_lit), vsini_lit, 'o', color = '#a6a6a6', label='Literature')
# PLOTTING SLOW VSINI FROM LITERATURE
plt.plot(vsini_slit_cl, vsini_slit, 'o', color = '#a6a6a6')
# PLOTTING VSINI FROM OUR WORK
plt.plot(vsini_cl_sl, vsini_sl, 'o', label='This Work' )
plt.errorbar(vsini_color, vsini_chad, yerr=vsini_chad_sig, fmt='bo', capsize=3)
plt.legend()
plt.savefig('vsini_colors.jpg', dpi=200)
Just use
plt.legend(numpoints=1)
The default behavior is to use 2 points, which is what you need to make a legend entry for lines.
See: legend user guide and plt.legend doc and legend doc