5

How to fix these kinks in the norm_pan and norm_tau curves? I tried using a quite high resolution and logarithmic spacing when defining t, but this did not fix the problem.

import numpy as np import matplotlib.pyplot as plt t = np.logspace(0, 4, 10**5, base=10) CP = 400 P_an = 1100 tau = 30 P = CP+P_an/(1+t/tau) dP_dPan = 1/(1+t/tau) dP_dtau = (P_an*t)/(tau**2*(1+t/tau)**2) S_CP = CP/P norm_pan = (dP_dPan - dP_dPan.min()) / (dP_dPan.max() - dP_dPan.min()) norm_tau = (dP_dtau - dP_dtau.min()) / (dP_dtau.max() - dP_dtau.min()) plt.figure(figsize=(6,4)) plt.plot(t, norm_pan, label=r'$\text{P}_\text{an}$') plt.plot(t, norm_tau, label=r'$\tau$') plt.plot(t, S_CP, label="CP") plt.vlines(tau, 0, max(norm_tau), linestyles=':', colors="dimgray", alpha=.4, lw=1.5) plt.xscale('symlog') plt.xlim(1, 10001) plt.ylim(0, 1.05) ax = plt.gca() ax.spines["top"].set_visible(False) ax.spines["right"].set_visible(False) ax.set_xticks([1, 10, tau, 100, 1000, 10000]) ax.set_xticklabels([1, 10, r'$\tau$', 100, 1000, 10000]) plt.legend(fontsize=9, frameon=False, loc='center right') plt.tight_layout() plt.show() 

Figure 1

I believe this is a plotting artifact which gets even more visible if plotting for the range plt.xlim(0.1, 100001)

Figure 2

Edit The solution to the problem makes me realize that an artifact likely rose concerning CP as well; however, this was harder to notice due to the slope of the curve near one.

7
  • maybe first check what values you have in P and tau. Maybe it needs more values in first part. You could also check how it looks when you draw only first part in resized window. Commented 21 hours ago
  • @furas What do you mean? tau is a parameter used for calculating P (see the code). t defines the number of plotted points. Commented 21 hours ago
  • what is green line with name tau? is it for variable tau or other variable? If it is different variable then check values in other variable Commented 21 hours ago
  • The green line is (dP_dtau - dP_dtau.min()) / (dP_dtau.max() - dP_dtau.min()) against t. Please read the code block, you will find everything in there. I admit that the labelling might be a bit misleading if only looking at the figures. Commented 21 hours ago
  • 1
    You have asked np.logspace to generate 4 points on the range [1...10^5].. Why are you surprised that you are seeing plotting artefacts? 40 is a more reasonable number (50 is the default). Commented 21 hours ago

2 Answers 2

4

You can simple change plt.xscale('symlog') to plt.xscale('log'). 'symlog' is an extension of the 'log' scale for negative values, which you do not need here. Naturally, this extension is not seamless, and it needs to remove values under a small threshhold. That is what is causing you issues here.

Figure without artefacts

Be careful if you need to plot for values starting at 0.1, you need to change t at the begining.

Full code:

import numpy as np import matplotlib.pyplot as plt t = np.logspace(-1, 4, 100) CP = 400 P_an = 1100 tau = 30 P = CP+P_an/(1+t/tau) dP_dPan = 1/(1+t/tau) dP_dtau = (P_an*t)/(tau**2*(1+t/tau)**2) S_CP = CP/P norm_pan = (dP_dPan - dP_dPan.min()) / (dP_dPan.max() - dP_dPan.min()) norm_tau = (dP_dtau - dP_dtau.min()) / (dP_dtau.max() - dP_dtau.min()) plt.figure(figsize=(6,4)) plt.plot(t, norm_pan, label=r'$\text{P}_\text{an}$') plt.plot(t, norm_tau, label=r'$\tau$') plt.plot(t, S_CP, label="CP") plt.vlines(tau, 0, max(norm_tau), linestyles=':', colors="dimgray", alpha=.4, lw=1.5) plt.xscale('log') plt.xlim(0.1, 10001) plt.ylim(0, 1.05) ax = plt.gca() ax.spines["top"].set_visible(False) ax.spines["right"].set_visible(False) ax.set_xticks([1, 10, tau, 100, 1000, 10000]) ax.set_xticklabels([1, 10, r'$\tau$', 100, 1000, 10000]) plt.legend(fontsize=9, frameon=False, loc='center right') plt.tight_layout() plt.show() 
Sign up to request clarification or add additional context in comments.

1 Comment

Indeed. I did not know about this, thank you!
0

As MrXerios pointed out, the plotting artifacts were due to applying symmetrical logarithimic scaling to x, i.e., plt.xscale('symlog').

After reading up on the documentation, I realized that 'symlog' applies linear scaling to a near-zero range, to avoid values going to infinity. This range is defined by the attribute linthresh, which is set to equal 2 by default (i.e., the scaling is linear for [-2, 2]).

Therefore, there is a solution to the problem by keeping symlog and including linthresh=1, as the minimum value on the x-axis was one in this example.

plt.xscale('symlog', linthresh=1) 

Figure 1

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.