Matplotlib scalarformatter not converting y-ticks to standard form - matplotlib

I am trying to use ScalarFormatter to convert my y-axis ticks into standard form, but after much experimenting I'm experiencing no success and I can't figure out why. MWE:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import scipy.constants as const
k = 1/(4*np.pi*const.epsilon_0)
def force_e(q_1,q_2,x):
return k*q_1*q_2/x**2
d = 10
delta = 0.1*d
x = np.linspace(0+delta,d-delta,1000)
q1 = 2e-6
q2 = -2e-6
q = 1e-9
F = force_e(q1,q,x) - force_e(q2,q,d-x)
fig,ax1 = plt.subplots(1, figsize=(6,6))
ax1.plot(x, F)
ax1.yaxis.set_major_formatter(mpl.ticker.ScalarFormatter(useMathText=True))
ax1.set_xlabel("Separation $r$ (m)")
ax1.set_ylabel("Force $F$ (N)")
plt.tight_layout()
plt.show()
It produces a figure as so:
where as I would like it to display 1.75x10^5 etc.

Related

Curve fitting exponential function with semilog x-axis

I'm having trouble fitting some date onto an exponential function with a semilog x-axis.
Following is the code:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
kd=np.array[0.735420099, 0.700823723, 0.647775947,0.613179572,0.573970346,0.54398682,0.454036244,0.371004942,0.292586491,0.271828666,0.21878089,0.165733114,0.157660626,0.151894563]
ADAR = np.array[0.001012268,0.002028379,0.004015198,0.005931555,0.007948127,0.010143277,0.019594977,0.039746044,0.076782168,0.101639121,0.193968714,0.574178304,0.778822803,0.9878803]
def func(x,a,c,d):
return a*np.exp(-c*x)+d
init_v = (1,1e-6,0)
opt,pcov = curve_fit(func,ADAR,kd,init_v)
a,c,d = opt
x2 = np.linspace(0.001,1)
y2 = func(x2,a,c,d)
plt.grid(True, which = "both")
fig = plt.figure()
ax = plt.gca()
ax.scatter(ADAR,kd, c = 'blue')
ax.set_xscale('log')
plt.xlim([0.001,1])
plt.ylim([0,0.8])
plt.plot(x2,y2, '-', label = 'fit')
plt.legend()
plt.title('Area pressure coefficient')
plt.xlabel('AD/AR')
plt.ylabel('kd')
plt.show
Trying to fit the scatter plot:
Using Scipy Curve_fit with initial guesses I am unable to get a close fit of the data. Am I using the wrong function for this?

I cannot fit my data logarithmically, How can I add log trendline?

So this is my code, it's written a little messy and my result is absolutely ridiculous. I have no idea how to fix it.
Also, the seaborn library does not work on my computer in any way.
.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data=pd.read_csv('Data.csv',encoding="latin1",sep=";",engine="python")
table = data.replace(0, 0.1)
plt.plot(table["RMDM"], table["BSURF"], color="#03012d", marker=".", ls="None", markersize=3, label="")
data['RMDM'] = data['RMDM'].astype(float)
data['BSURF'] = data['BSURF'].astype(float)
fig, ax = plt.subplots()
x=data['BSURF']
y=data['RMDM']
ax.set_yscale('log')
ax.set_xscale('log')
plt.style.use('classic')
plt.xlabel('B_LC')
plt.ylabel('RM/DM')
plt.plot(x,y, 'og')
from scipy.stats import linregress
df = data.loc[(data['RMDM'] >0) & (data['BSURF'] >0)]
stats = linregress(np.log10(df["RMDM"]),np.log10(df["BSURF"]))
m = stats.slope
b = stats.intercept
r = stats.rvalue
x = np.logspace(-1, 5, base=10)
y = (m*x+b)
plt.plot(x, y, c='orange', label="fit")
plt.legend()
#m,c=np.polyfit(x,y,1)
#plt.plot(x,m*x+c)
plt.grid()
plt.show()
lmplot can be used to create a linear line through your data. you correctly used np.log for the linear regression data. keep x in terms of the log.
df['log_col1']=np.log(df['col1'])
sns.lmplot(x='log_col1','y='target', data=df, ci=None)
sns.scatterplot(y='target',x='log_col1',data=df)
plt.show()

Matplotlib: strange minor ticks with log base 2 colorbar

I am plotting some contours with tricontourf. I want the colormap to be scaled in log values and tick labels and colours bounds to be in log base 2. Here's my code:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as tri
import matplotlib.ticker as ticker
import matplotlib.colors as colors
section = 'T7'
data = np.loadtxt( section + '_values.dat')
x = data[:,0]
y = data[:,1]
z = data[:,2]
triang = tri.Triangulation(x,y)
fig1, ax1 = plt.subplots()
ax1.set_aspect('equal')
bounds = [2.**-1,2.**1,2**3,2**5,2**7,2**9]
norm = colors.LogNorm()
formatter = ticker.LogFormatter(2)
tcf = ax1.tricontourf(triang, z, levels = bounds, cmap='hot_r', norm = norm )
fig1.colorbar(tcf, format=formatter)
plt.show()
And here's the result:
What are thos ugly minor ticks and how do I get rid of them?
Using Matplotlib 3.3.0 an Mac OS
You could use cb.ax.minorticks_off() to turn off the minor tick and cb.ax.minorticks_on() to turn it on.
cb = fig1.colorbar(tcf, format=formatter)
cb.ax.minorticks_off()
matplotlib.pyplot.colorbar returns a Colorbar object which extends ColorbarBase.
You can find that two functions in the document of class matplotlib.colorbar.ColorbarBase.

Colorbar scientific notation, change e^ to 10^

I am using scientific notation in a colorbar within a 2D plot. I want to write 10^{-3} instead of e-3. I tried to change that (see code below) but it does not work...
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
x = np.random.rand(100)
y = np.random.rand(100)
z = np.random.rand(100)*0.001
x=x.reshape((10,10))
y=y.reshape((10,10))
z=z.reshape((10,10))
fig, ax = plt.subplots(figsize=(8,6))
cs = ax.contourf(x,y,z, 10)
plt.xticks(fontsize=16,rotation=0)
plt.yticks(fontsize=16,rotation=0)
cbar = plt.colorbar(cs,)
cbar.set_label("test",fontsize = 22)
cbar.formatter.set_scientific(True)
cbar.formatter.set_powerlimits((0, 0))
cbar.ax.tick_params(labelsize=16)
cbar.ax.yaxis.get_offset_text().set_fontsize(22)
cbar.ax.xaxis.major.formatter._useMathText = True
cbar.update_ticks()
plt.savefig("test.png")
It seems you want a ScalarFormatter with mathtext in use.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
x = np.tile(np.arange(10), 10).reshape((10,10))
y = np.repeat(np.arange(10),10).reshape((10,10))
z = np.sort(np.random.rand(100)*0.001).reshape((10,10))
fig, ax = plt.subplots(figsize=(8,6))
cs = ax.contourf(x,y,z, 10)
fmt = matplotlib.ticker.ScalarFormatter(useMathText=True)
fmt.set_powerlimits((0, 0))
cbar = plt.colorbar(cs,format=fmt)
plt.show()

Matplotlib double legend

With my code I get 2 equations in the legend that are the same. I don't how why it is so. I just want to correct this by making it only one equation. How can I do that? This equation is the line fit result of some of the data below.
Thanks in advance!
import matplotlib.pyplot as plt
import numpy as np
import plotly.plotly as py
import plotly.tools as tls
from sympy import S, symbols
import sympy
y = [2.7,2.3,1.9,1.5,1.3,1.0,0.8,0.6,0.5,0.4,0.2,0.1,0.0,0.0,-0.20,-0.2]
y = [i*10**(-16) for i in y]
x = [0,0.05,0.10,0.15,0.20,0.25,0.30,0.40,0.45,0.50,0.55,0.60,0.65,0.70,0.75,0.80]
e_y = [10**(-17)]* 16
e_x = [0.001] * 16
fig= plt.figure()
ax = fig.add_subplot(111)
ax.errorbar(x,y, yerr=e_y,xerr=0.001,fmt='-o')
ax.set_title('Current vs. Potential')
ax.set_xlabel('Retarding Potential')
ax.set_ylabel('Photocell Current')
x=x[:7]
y=y[:7]
e_y=e_y[:7]
e_x=e_x[:7]
#line fit:
fit=np.polyfit(x,y,1)
fit_fn = np.poly1d(fit)
a=symbols("x")
line = sum(S(format(v))*a**i for i, v in enumerate(fit[::-1]))
eq_latex = sympy.printing.latex(line)
plt.plot(x,y,x,fit_fn(x),label="${}$".format(eq_latex))
plt.legend(fontsize='small')
plt.show()
I solved this using the following:
#import matplotlib.patches as mpatches
plt.plot(x,y,x,fit_fn(x))
eqn = mpatches.Patch(color='green',label="${}$".format(eq_latex))
plt.legend(handles=[eqn])
instead of
plt.plot(x,y,x,fit_fn(x),label="${}$".format(eq_latex))
plt.legend(fontsize='small')