Set xticklabel overlaps old xtick - python

I am trying to modify the x-ticks of a plot, but one of the tick labels automatically generated by matplotlib does not disappear, and the one I assign overlaps it. The code is:
ax[0].plot((zspace+1.),dndt_vs_z_9, color='blue', label=r'$M_s = 10^9$')
ax[0].plot((zspace+1.),dndt_vs_z_10, color='red', label=r'$M_s = 10^{10}$')
ax[0].plot((zspace[zspace<=2]+1.),dndt_vs_z_11[zspace<=2], color='green', label=r'$M_s = 10^{11}$')
ax[0].plot((zspace[zspace<=2]+1.),(1./2.)*dndt_vs_z_11[zspace<=2], color='black')
ax[0].plot((zspace[zspace<=2]+1.),0.65*dndt_vs_z_11[zspace<=2], color='black')
ax[0].plot(gomez_11_x,gomez_11_y,color='blue', linestyle='dashed')
ax[0].plot(gomez_10_x,gomez_10_y,color='red', linestyle='dashed')
ax[0].plot(gomez_9_x,gomez_9_y,color='green', linestyle='dashed')
#ax[0].scatter(ill_shmr_z,ill_shmr_dndw_model_11)
ax[0].set_yscale('log')
ax[0].set_xscale('log')
ax[0].set_xticks([1,2,3,4,5], minor=True)
ax[0].set_xticklabels([1,2,3,4,5], minor=True, fontsize='20')
ax[0].set_xlim([1,5])
ax[0].set_ylim([1e-2,1e1])
ax[0].legend(loc='best', fontsize='20')
ax[0].grid(b = True, which='major')
ax[0].grid(b = True, which='minor', axis='x')
ax[0].set_xlabel(r'$1+z$', fontsize='15')
ax[0].set_ylabel(r'$\frac{dN}{dt}$', fontsize='20')
and the result is:

The problem here comes from mixing major and minor ticks when using log scale. A solution in your example case would be to remove the major ticks using a NullLocator and only use the minor ticks:
A small example would be:
import matplotlib.pyplot as plt
import matplotlib.ticker
fig, (ax1, ax2) = plt.subplots(1,2, figsize=(12,7))
ax1.loglog([1,2,3,4,5])
ax1.set_xticks([1,2,3,4,5],minor=True)
ax1.set_xticklabels([1,2,3,4,5], minor=True, fontsize='20')
ax1.set_title("Reproduce problem")
ax2.loglog([1,2,3,4,5])
ax2.set_xticks([1,2,3,4,5],minor=True)
ax2.set_xticklabels([1,2,3,4,5], minor=True, fontsize='20')
ax2.xaxis.set_major_locator(matplotlib.ticker.NullLocator())
ax2.set_title("Apply fix")
plt.show()

Related

Matplotlib: Minor ticks not showing

for some reason my minor ticks in my plot are not showing anymore. Yesterday, I still had them in and I just don't know what I changed such that they disappeared...
Here is my code:
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
fig, axs = plt.subplots(nrows=1, ncols=1, sharex=True, sharey=True)
font = font_manager.FontProperties(family='sans-serif', style='normal', size=16)
for (i, alpha) in enumerate(alpha_values_small):
filt = data[
(data["Topology"] == "UNIFORM") &
(data["HashingPowerDistribution"] == "UNIFORM") &
(data["CentralityMeasure"] == "RANDOM") &
(data["Alpha"] == alpha)]
axs.plot(
1/filt["Gamma"],
filt["OrphanBlockRate"],
label=r"$\alpha = {}$".format(np.round(alpha, 2)),
color=color_list[i],
marker=marker_list[i],
linestyle="",
markersize=12,
linewidth=1.5,
markeredgewidth=2,
)
axs.set_xscale("log")
axs.set_xlabel(r"$\lambda_{nd}$", fontfamily='sans-serif', fontsize=22)
axs.set_ylabel("Orphan block rate", fontfamily='sans-serif', fontsize=22)
axs.tick_params(which='major', direction="in", top=True, left=True, right=True, width=1.5, size=6, labelsize=16)
axs.tick_params(which='minor', direction="in", top=True, left=True, right=True, width=1, size=4, labelsize=16)
axs.legend(prop=font, frameon=False)
plt.show()
This produces the following output:
Does anyone know why it's not showing my minor ticks?
Thank you so much in advance!!
I believe minor ticks are visible only if there is enough space.
You may try to increase the figure size
fig, axs = plt.subplots(..., figsize=(10,10))
or decrease the font size.

Seaborn: How to specify plot minor ticks and gridlines in all plots when using lmplot?

I'm trying to get minor ticks and gridlines plotted in all plots when using lmplot, using the code below:
sns.set(context="notebook", style='white', font_scale=2)
g=sns.lmplot(data=data ,
x="x",
y="y",
col="item", # or use rows to display xplots in rows (one on top of the other)
fit_reg=False,
col_wrap=2,
scatter_kws={'linewidths':1,'edgecolor':'black', 's':100}
)
g.set(xscale='linear', yscale='log', xlim=(0,0.4), ylim=(0.01, 10000))
for ax in g.axes.flatten():
ax.tick_params(axis='y', which='both', direction='out', length=4, left=True)
ax.grid(b=True, which='both', color='gray', linewidth=0.1)
for axis in [ax.yaxis, ax.xaxis]:
formatter = FuncFormatter(lambda y, _: '{:.16g}'.format(y))
axis.set_major_formatter(formatter)
sns.despine()
g.tight_layout()
# Show the results
plt.show()
So far, only major ticks and gridlines are shwon in all plots.
Thanks for any advice for solving this
Your code work fine for me.
I think the problem is that when the major labels are too big, matplotlib chooses not to display the minor ticks, and hence the minor grid lines. You may either change font_scale, or increase the size of your figure (see height= in lmplot())
Consider the following code with font_scale=1
tips = sns.load_dataset('tips')
sns.set(context="notebook", style='white', font_scale=1)
g = sns.lmplot(x="total_bill", y="tip", col="day", hue="day",
data=tips, col_wrap=2, height=3)
g.set(xscale='linear', yscale='log')
for ax in g.axes.flatten():
ax.tick_params(axis='y', which='both', direction='out', length=4, left=True)
ax.grid(b=True, which='both', color='gray', linewidth=0.1)
for axis in [ax.yaxis, ax.xaxis]:
formatter = matplotlib.ticker.FuncFormatter(lambda y, _: '{:.16g}'.format(y))
axis.set_major_formatter(formatter)
sns.despine()
g.tight_layout()
# Show the results
plt.show()
compare with the result using font_scale=2

Color all tick labels in scientific notation

I want to color the tick labels of my left vertical axis. However, the following code:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([1,5,10],[1,5,10])
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlim([1e0,1e1])
ax.set_ylim([1e0,1e1])
ax.yaxis.label.set_color('b')
ax.spines['left'].set_edgecolor('b')
ax.tick_params(axis='y', colors='b')
plt.savefig('test.png')
plt.show()
fails to color all lables:
Use
ax.tick_params(axis='y', colors='b', which='both')
where both corresponds to the major as well as the minor ticks.
Output

How to Return a MatPlotLib Figure with its corresponding Legend

I'm trying to define a function which returns a pre-styled figure with certain grid, style, width and other properties. However, when I return the fig and its axes, the legend is missing. Here's a simplified example:
def getfig():
plt.style.use('default')
fig, axs = plt.subplots(1, 1, figsize=(1,1), sharey=False)
if issubclass(type(axs),mpl.axes.SubplotBase):
axs=[axs]
for ax in axs:
ax.grid(color='grey', axis='both', linestyle='-.', linewidth=0.4)
ax.legend(loc=9, bbox_to_anchor=(0.5, -0.3), ncol=2)
return fig,axs
fig,axs=getfig()
axs[0].plot(range(10), label="label")
What am I missing?
Thanks!
UPDATE:
This is what I'm using so far but I think there really should be a way to force all future legends associated to a figure to have a certain style.
def fig_new(rows=1,columns=1,figsize=(1,1)):
plt.style.use('default')
fig, axs = plt.subplots(rows,columns, figsize=figsize, sharey=False)
if issubclass(type(axs),mpl.axes.SubplotBase):
axs=[axs]
for ax in axs:
ax.grid(color='grey', axis='both', linestyle='-.', linewidth=0.4)
return fig,axs
def fig_leg(fig):
for ax in fig.get_axes():
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.3), ncol=5)
fig,axs=fig_new()
axs[0].plot(range(10), label="label")
fig_leg(fig)
You need to call the legend after an artist with a label is plotted to the axes.
An option is to let the function return the arguments to use for the legend afterwards.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
def getfig():
plt.style.use('default')
fig, axs = plt.subplots(1, 1, figsize=(1,1), sharey=False)
if issubclass(type(axs),mpl.axes.SubplotBase):
axs=np.array([axs])
legendkw = []
for ax in axs:
ax.grid(color='grey', axis='both', linestyle='-.', linewidth=0.4)
legendkw.append(dict(loc=9, bbox_to_anchor=(0.5, -0.3), ncol=2))
return fig,axs,legendkw
fig,axs,kw=getfig()
axs[0].plot(range(10), label="label")
for i,ax in enumerate(axs.flat):
ax.legend(**kw[i])
plt.show()

How to move specific x-axis (minor) tick labels to the top of a figure in matplotlib?

I want to keep the major tick labels, that matplotlib has automatically generated, in their default position under the figure. However, I myself added some minor ticks (with vertical lines) at specific x values, but their labels don't fit between the default major ticks. How can I move these labels to the top of the figure?
My code for reference:
meta = comparisons['meta']
lagsAnycast = np.array(meta['lagsAnycast'])
lagsPenultimate = np.array(meta['lagsPenultimate'])
avgLagAnycast = meta['avgLagAnycast']
avgLagPenultimate = meta['avgLagPenultimate']
plt.step(lagsAnycast, (np.arange(lagsAnycast.size) + 1)/lagsAnycast.size, color='k', label='to anycast IPs', linewidth=1.5)
plt.step(lagsPenultimate, (np.arange(lagsPenultimate.size) + 1)/lagsPenultimate.size, color='k', label='to penultimate IPs', linewidth=1)
plt.axvline(round(avgLagAnycast,1), ls="dashed", color="k", label="average lag to anycast IPs", linewidth=1.5)
plt.axvline(round(avgLagPenultimate,1), ls="dashed", label="average lag to penultimate IPs", color="k", linewidth=1)
plt.axis([-0.34,60,0.7,1])
plt.xlabel("Lag (ms)")
plt.ylabel("CDF")
existingTicks = (plt.xticks())[0][1:].tolist()
plt.gca().xaxis.grid(True, which='major')
plt.gca().xaxis.grid(False, which='minor')
plt.gca().tick_params(axis="x", which="minor", direction="out", top=True)
plt.gca().set_xticks([round(avgLagAnycast,1), round(avgLagPenultimate,1)], minor=True)
plt.legend(loc='right', fontsize=10)
plt.grid(True, ls="dotted")
majorFormatter = FormatStrFormatter('%g')
plt.gca().xaxis.set_major_formatter(majorFormatter)
plt.savefig(os.path.join(os.getcwd(), "datasets/plots/CDF1.png"))
You can use Locators and Formatters to set the ticks and ticklabels and turn them on or off using tick_params:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
x = np.linspace(-3,3)
plt.plot(x, np.sin(x))
ticks = [-np.pi/2,np.pi/2.]
labels = [r"$-\frac{\pi}{2}$",r"$\frac{\pi}{2}$"]
ax = plt.gca()
ax.xaxis.set_minor_locator(ticker.FixedLocator(ticks))
ax.xaxis.set_minor_formatter(ticker.FixedFormatter(labels))
# Set visibility of ticks & tick labels
ax.tick_params(axis="x", which="minor", direction="out",
top=True, labeltop=True, bottom=False, labelbottom=False)
plt.show()

Categories