I have the following code snippet to do a plot with logscale for x-axis :
# Number of values for loop
num_prior_loop = 100
# Declare prior array
prior_fish = np.zeros(num_prior_loop)
prior_start = 0
prior_end = 3
prior_fish = np.logspace(prior_start,prior_end,num_prior_loop)**2
# Declare FoM final array
FoM_final = np.zeros(num_prior_loop)
...
# Plot
fig, ax = plt.subplots()
ax.plot(prior_fish, FoM_final)
#ax.set_xticks([np.linspace(prior_start,prior_end)])
#ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
plt.xlabel(r'Prior on 5 ratios '+r'$\alpha = b_{sp}/b_{ph}$'+' in Fisher GCsp', fontsize=10)
plt.ylabel('FoM')
plt.title('FoM vs Prior - Prior on both GCsp and XC', fontsize=10)
plt.savefig('FoM_vs_Prior_alpha_on_both_GCsp_and_XC.pdf')
that produces the following figure :
Now, I would like to do a modification, that is, I want the xtick 10^0 up to 10^6 to be automatically replaced by 1, 10^-1, 10^-2, ...., 10^-6.
I say automatically since the start and end of the 2 bounds (1 and 10^-6) may vary.
UPDATE 1: I tried the solution suggested by @max
in answer below but it fails :
Here what I got :
If I do :
for txt in axs.get_xticklabels():
# get position
x,y = txt.get_position()
print('x,y =', x,y)
# value/formatting
val = txt.get_text()
# create new label
if x == 1 or x == 0:
val_new = f'${round(x)}$'
else:
val_new = '$\\mathdefault{10^{' + f'{round(np.log10(1/x))}' + '}}$'
# append
xTickLabel.append( Text(x,y,val_new) )
# set labels
axs.set_xticklabels( xTickLabel )
# Plot and save
plt.plot(prior_fish, FoM_final)
plt.draw()
plt.savefig('FoM_vs_Prior_alpha_on_both_GCsp_and_XC.png')
I get only zeros :
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
x,y = 0 0
and printing val
returns always empty value.
Here the entire code :
# Plot
fig, axs = plt.subplots()
axs.set_xscale('log')
plt.draw()
plt.xlabel(r'Prior on 5 ratios '+r'$\alpha = b_{sp}/b_{ph}$'+' in Fisher GCsp', fontsize=10)
plt.ylabel('FoM')
plt.title('FoM vs Prior - Prior on both GCsp and XC', fontsize=10)
# create new labels
xTickLabel = []
for txt in axs.get_xticklabels():
# get position
x,y = txt.get_position()
# value/formatting
val = txt.get_text()
# create new label
if x == 1 or x == 0:
val_new = f'${round(x)}$'
else:
val_new = '$\\mathdefault{10^{' + f'{round(np.log10(1/x))}' + '}}$'
# append
xTickLabel.append( Text(x,y,val_new) )
# set labels
axs.set_xticklabels( xTickLabel )
# Plot and save
plt.plot(prior_fish, FoM_final)
plt.draw()
plt.savefig('FoM_vs_Prior.pdf')
Where is the bug ? How to get values different values of "0" and "1" in order to avoid to be in the case
if x == 1 or x == 0:
val_new = f'${round(x)}$'
It seems that you want to modify the text-labels directly. Have a look at the code below. We get the position of the ticks, invert the x
-value, and change the matplotlib.text.Text
-object (or rather, I create new ones). The trick is that the positions remain the same; we just change the text that is displayed at this position/tick-label:
from matplotlib import pyplot as plt
from matplotlib.text import Text
import numpy as np
fig, axs = plt.subplots(2,1)
# first axis
axs[0].set_xscale('log')
axs[0].set_yscale('log')
axs[0].scatter(2**np.arange(10), 2**np.arange(10))
plt.draw()
# second axis
axs[1].set_xscale('log')
axs[1].set_yscale('log')
axs[1].scatter(2**np.arange(10), 2**np.arange(10))
# create new labels
xTickLabel = []
for txt in axs[0].get_xticklabels():
# get position
x,y = txt.get_position()
# value/formatting
val = txt.get_text()
# create new label
if x == 1 or x == 0:
val_new = f'${round(x)}$'
else:
val_new = '$\\mathdefault{10^{' + f'{round(np.log10(1/x))}' + '}}$'
# append
xTickLabel.append( Text(x,y,val_new) )
# set labels
axs[1].set_xticklabels( xTickLabel )
plt.draw()