The next code plots three subplots.
from ipywidgets import widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
%matplotlib notebook
fig, (ax1, ax2,ax3) = plt.subplots(nrows=3, figsize=(10,9))
line1, = ax1.semilogx([],[], label='Multipath')
hline1 = ax1.axhline(y = 0, linewidth=1.2, color='black',ls='--')
text1 = ax1.text(0, 0, "T Threshold",
verticalalignment='top', horizontalalignment='left',
transform=ax1.get_yaxis_transform(),
color='brown', fontsize=10)
#ax1.set_xlabel('Separation Distance, r (m)')
ax1.set_ylabel('Received Power, $P_t$ (dBm)')
ax1.grid(True,which="both",ls=":")
ax1.legend()
line2, = ax2.semilogx([],[], label='Monostatic Link')
hline2 = ax2.axhline(y = 0, linewidth=1.2, color='black',ls='--')
text2 = ax2.text(0, 0, "R Threshold",
verticalalignment='top', horizontalalignment='left',
transform=ax2.get_yaxis_transform(),
color='brown', fontsize=10)
#ax2.set_xlabel('Separation Distance, r (m)')
ax2.set_ylabel('Received Power, $P_t$ (dBm)')
ax2.grid(True,which="both",ls=":")
ax2.legend()
#line3, = ax3.semilogx([],[])
line3 = ax3.scatter([],[], c='blue', alpha=0.75, edgecolors='none', s=6)
ax3.set_xlabel('Separation Distance, r (m)')
ax3.set_ylabel('Probability of error')
ax3.grid(True,which="both",ls=":")
ax3.set_xscale('log')
#ax3.set_xlim((0.55,13.5))
ax3.set_ylim((0,1))
def update_plot(h1, h2):
D = np.arange(0.5, 12.0, 0.0100)
r = np.sqrt((h1-h2)**2 + D**2)
freq = 865.7 #freq = 915 MHz
lmb = 300/freq
H = D**2/(D**2+2*h1*h2)
theta = 4*np.pi*h1*h2/(lmb*D)
q_e = H**2*(np.sin(theta))**2 + (1 - H*np.cos(theta))**2
q_e_rcn1 = 1
P_x_G = 4 # 4 Watt EIRP
sigma = 1.94
N_1 = np.random.normal(0,sigma,D.shape)
rnd = 10**(-N_1/10)
F = 10
y = 10*np.log10( 1000*(P_x_G*1.622*((lmb)**2) *0.5*1) / (((4*np.pi*r)**2) *1.2*1*F)*q_e*rnd*q_e_rcn1 )
line1.set_data(r,y)
hline1.set_ydata(-18)
text1.set_position((0.02, -18.8))
ax1.relim()
ax1.autoscale_view()
######################################
rd =np.sqrt((h1-h2)**2 + D**2)
rd = np.sort(rd)
P_r=0.8
G_r=5 # 7dBi
q_e_rcn2 = 1
N_2 = np.random.normal(0, sigma*2, D.shape)
rnd_2 = 10**(-N_2/10)
F_2 = 126
y = 10*np.log10( 1000*(P_r*(G_r*1.622)**2*(lmb)**4*0.5**2*0.25)/((4*np.pi*rd)**4*1.2**2*1**2*F_2)*
q_e**2*rnd*rnd_2*q_e_rcn1*q_e_rcn2 )
line2.set_data(rd,y)
hline2.set_ydata(-80)
text2.set_position((0.02, -80.8))
ax2.relim()
ax2.autoscale_view()
#######################################
P_r = y
SNR = P_r - ( 20 + 10*np.log10(1.6*10**6)-174 )
CIR = P_r -( -100)
SNR_linear = 10**(SNR/10)
CIR_linear = (10**(CIR/10))/1000
SNIR = 1/( 1/SNR_linear + 1/CIR_linear )
K_dB = 3
K = 10**(K_dB/10)
BER = (1+K)/(2+2*K + SNIR)*np.exp(-3*SNIR/(2+K+SNIR))
prob_error = 1-((1-BER )**6)
#line3.set_data(rd,prob_error)
line3.set_offsets(np.c_[rd,prob_error])
ax3.relim()
ax3.autoscale_view()
fig.canvas.draw_idle()
r_height = widgets.FloatSlider(min=0.5, max=4, value=0.9, description= 'R_Height:')
t_height = widgets.FloatSlider(min=0.15, max=1.5, value=0.5, description= 'T_Height:')
widgets.interactive(update_plot, h1=r_height, h2=t_height)
Subplots 1st and 2nd change their axis limits with variations of the input parameters R_Height and T_Height. However, subplot 3rd does not make the relim()
and autoscale()
of the plot.
Is there any way to change the limits of the x-axis in a similar way of subplots 1st and 2nd?.
Regards
However, subplot 3rd does not make the relim () and autoscale () of the plot. Is there any way to change the limits of the x-axis in a similar way of subplots 1st and 2nd?.
We’ll select our data range, then we’ll insert Scatter Plot from the Insert tab. Firstly, select the cell range C4:D10. Secondly, from the Insert tab >>> Insert Scatter (X,Y) or Bubble Chart >>> select Scatter. This will display the basic Correlation Scatter plot. Now, we’ll format the Scatter plot. At first, we’ll change the Chart Title –
A Scatter Plot shows the relationship between two quantitative variables in a data set. The values of the dependent variable appear on the horizontal axis, while independent variables appear on the vertical axis of the chart. Use the chart if your goal is to uncover hidden relationships of key data points.
autoscale () function matplotlib.pyplot.autoscale () is a method for simple axis view autoscaling. It turns autoscaling on or off, and then, if autoscaling for either axis is on, it performs the autoscaling on the specified axis or axes. Syntax: matplotlib.pyplot.autoscale (enable=True, axis=’both’, tight=None)
Both .relim()
and .autoscale_view()
do not take effect when the axes bounds have previously been set via .set_ylim()
. So .set_ylim()
needs to be removed from the code.
In addition updating the limits of a scatter plot (which is a matplotlib.collections.PathCollection
) is a bit more complicated than for other plots.
You would first need to update the datalimits of the axes before calling autoscale_view()
, because .relim()
does not work with collections.
ax.ignore_existing_data_limits = True
ax.update_datalim(scatter.get_datalim(ax.transData))
ax.autoscale_view()
Here is a minimal reproducible example:
from ipywidgets import widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
%matplotlib notebook
x = np.arange(10)
fig, ax = plt.subplots()
scatter = ax.scatter(x,x, label="y = a*x+b")
ax.legend()
def update_plot(a, b):
y = a*x+b
scatter.set_offsets(np.c_[x,y])
ax.ignore_existing_data_limits = True
ax.update_datalim(scatter.get_datalim(ax.transData))
ax.autoscale_view()
fig.canvas.draw_idle()
a = widgets.FloatSlider(min=0.5, max=4, value=1, description= 'a:')
b = widgets.FloatSlider(min=0, max=40, value=10, description= 'b:')
widgets.interactive(update_plot, a=a, b=b)
As written in the documentation for Axes.relim()
, Collections
(which is the type returned by scatter()
) are not supported at the moment.
Therefore you have to ajust the limits manually, something like
(...)
line3.set_offsets(np.c_[rd,prob_error])
ax3.set_xlim((min(rd),max(rd)))
ax3.set_ylim((min(prob_error),max(prob_error)))
It seems to me that all your plot share the same x values, though? If that's the case, you might want to use fig, (ax1, ax2,ax3) = plt.subplots((...), sharex=True)
. You will still have to set the ylim for ax3 by hand, but at least your x-axes will be the same across all subplots.
EDIT: I realize now that it looks like your data in ax3
are bound between [0-1], and that you probably don't need to change the ylim() and that sharing the x-axis with the other subplots should be enough.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With