Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make relim() and autoscale() in a scatter plot

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

like image 746
user1993416 Avatar asked Jul 13 '18 10:07

user1993416


People also ask

Does subplot 3rd make the relim and autoscale of the plot?

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?.

How to create a scatter plot in Excel?

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 –

What is a scatter plot in ABA?

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.

How do I AutoScale in Matplotlib?

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)


2 Answers

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)
like image 189
ImportanceOfBeingErnest Avatar answered Oct 22 '22 05:10

ImportanceOfBeingErnest


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 ax3are 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.

like image 21
Diziet Asahi Avatar answered Oct 22 '22 06:10

Diziet Asahi