Multiple plots on the same graph - python-3.x

I want to plot on the same graph one function (data coming from an array) and the line between (xmin,ymin) to (xmax,ymax) of data
import numpy as np
import matplotlib.pyplot as plt
exo_data = np.loadtxt('./exoplanets.dat')
au2m = 149597870700
day2seconds = 86400
M_Jupiter = 1.898e27
M_Sun = 1.989e30
G = 6.674e11
R=exo_data[:,0]*au2m
T=exo_data[:,1]*day2seconds
Mp=exo_data[:,2]*M_Jupiter
Ms=exo_data[:,3]*M_Sun
Mstar=np.mean(Ms)
C=(mth.pi*4)/G*Mstar
x=R**3
y=T**2
xmin=np.min(R)
ymin=np.min(T)
xmax=np.max(R)
ymax=np.max(T)
plt.plot([xmin,ymin], [xmax,ymax], color='red')
plt.plot(x,y, 'ro', color='blue')
plt.show
plt.close
I have only the first plot in spyder console, not the second one
Expected this :

I'm not sure if it's going to work for you, I suggest you to try the following
plt.plot([xmin,ymin], [xmax,ymax], x, y,'ro', color = 'red')
plt.show

Try to run the script not in the spider console, but in the editor to the left of it. The console processes command by command, therefore, it will process one plot at the time and print it in the same way.
Create a file code.py with your script, and then run it. You can do this with the play button in spyder, or by going to a console and typing python code.py.
Proof are doing everything right. As stated here. This should work:
from numpy import *
import math
import matplotlib.pyplot as plt
t = linspace(0, 2*math.pi, 400)
a = sin(t)
b = cos(t)
c = a + b
plt.plot(t, a, 'r') # plotting t, a separately
plt.plot(t, b, 'b') # plotting t, b separately
plt.plot(t, c, 'g') # plotting t, c separately
plt.show()
And should produce this.

Finally it works... It's my fault. I declared G with e11 and it must be e-11

Related

Get Tangent Point of a Curve

I have the following df (I will attach in the post):
Then I plot two columns, the called Price and the called OG. And it has show something like this:
plt.plot(out["PRICE"], out["OG [%]"])
So I want to get the tangent point(x,y) that optimize the curve. In the image I can see that is nearby (80, 0.160), but how can I get this coordenate automatically, considering that the curve could change in the future ?
Thanks in advance!
DF in CSV:
,INCREASE [%],PRICE,INCREASE,QTY,GPS,NNS,OG [%]
0,0.0,47.69,0.0,239032932.10219583,11399480531.953718,9649069936.361042
1,0.1,52.458999999999996,4.769,267545911.79200616,14035190986.69685,11961949944.986732,0.27315694384293565
2,0.2,57.227999999999994,9.538,296058891.48181653,16942858241.721395,14546786753.89384,0.24307636032561325
3,0.30000000000000004,61.997,14.307000000000002,324571871.1716268,20122482297.027348,17403580363.082355,0.21857913428577896
4,0.4,66.76599999999999,19.076,353084850.8614371,23574063152.614704,20532330772.55227,0.198325906714522
5,0.5,71.535,23.845,381597830.5512475,27297600808.483486,23933037982.30361,0.18134997420002735
6,0.6000000000000001,76.304,28.614000000000004,410110810.2410579,31293095264.633682,27605701992.33637,0.16694472549220507
7,0.7000000000000001,81.07300000000001,33.383,438623789.93086815,35560546521.06528,31550322802.650528,0.1545858626459231
8,0.8,85.842,38.152,467136769.6206784,40099954577.778275,35766900413.246086,0.14387833953735796
9,0.9,90.61099999999999,42.921,495649749.3104888,44911319434.7727,40255434824.12307,0.13452003951711053
10,1.0,95.38,47.69,524162729.0002991,49994641092.04852,45015926035.28145,0.12627665505254082
11,1.1,100.149,52.459,552675708.6901095,55349919549.605774,50048374046.72126,0.11896408514089048
12,1.2000000000000002,104.918,57.22800000000001,581188688.3799199,60977154807.444435,55352778858.44248,0.11243592554246645
13,1.3,109.687,61.997,609701668.0697302,66876346865.56449,60929140470.44511,0.10657445172186328
14,1.4000000000000001,114.456,66.766,638214647.7595404,73047495723.96596,66777458882.729126,0.10128402946033532
15,1.5,119.225,71.535,666727627.4493507,79490601382.64883,72897734095.29456,0.09648623602161768
16,1.6,123.994,76.304,695240607.1391611,86205663841.61314,79289966108.14143,0.09211620281895366
17,1.7000000000000002,128.763,81.07300000000001,723753586.8289715,93192683100.85886,85954154921.26971,0.08811984166718287
18,1.8,133.53199999999998,85.842,752266566.5187817,100451659160.38594,92890300534.67935,0.08445171808362244
19,1.9000000000000001,138.301,90.611,780779546.208592,107982592020.19447,100098402948.37045,0.08107340396640193
20,2.0,143.07,95.38,809292525.8984023,115785481680.28442,107578462162.34296,0.07795218934826136
This particular curve does not have and inflection point or "knee" (elbow):
from kneed import KneeLocator
kn = KneeLocator(x = out['PRICE'], y = out['OG [%] '], curve='convex', direction='decreasing')
print(kn.knee)
None
But if it did, you would do it like this:
y = [7342, 6881, 6531,
6356, 6209, 6094,
5980, 5880, 5779,
5691, 5617, 5532,
5467, 5395, 5345,
5290, 5243, 5207,
5164]
x = range(1, len(y)+1)
import kneed
from kneed import KneeLocator
kn = KneeLocator(x, y, curve='convex', direction='decreasing')
print(kn.knee)
print(round(kn.knee_y, 3))
import matplotlib.pyplot as plt
plt.xlabel('x')
plt.ylabel('y')
plt.plot(x, y, 'bx-')
plt.vlines(kn.knee, plt.ylim()[0], plt.ylim()[1], linestyles='dashed')
where
(print(kn.knee),print(round(kn.knee_y, 3)))
(5,6209)
gives you the coordinates of the knee.

Updating a plot in Python

My situation is this: I am developing a Jupyter-lab notebook to exemplify engineering topics. I find myself in the need of plotting something in an axes object within a figure, and then using a slider interact changing a value to update the plot.
Here is a MWE (or at least a shorter Working Example):
import ipywidgets as widgets
from ipywidgets import interact
import numpy as np
import matplotlib.pyplot as plt
global ax1
global fig
fig, (ax1) = plt.subplots(ncols=1, subplot_kw=dict(projection='polar'))
RAD = np.array([0.85, 0.85, 0.85])
ANG = np.array([np.pi/2, np.pi*(2/3+1/2), np.pi*(1/2-2/3)])
c = ax1.scatter(ANG, RAD)
ax1.set_ylim([0, 1])
ax1.set_yticklabels([])
def h(rh):
RADp = np.array([rh, rh, rh])
ANGp = np.array([-np.pi/2, np.pi*(2/3-1/2), np.pi*(-1/2-2/3)])
cp = ax1.scatter(ANGp, RADp)
ax1.add_artist(cp)
plt.show()
return (rh)
interact(h, rh = widgets.FloatSlider(min=0, max=1, step=0.001, value=1));
In this example I create the figure fig and its axes ax1 declared as global variables (so that they will be available within function h. Then using RAD and ANG I create a scatter plot c.
Afterwards using the interact widget I would like to have three crosses change position along the r axis by changing the value of rh with the slider.
I don't get any error, but neither get I any crosses at all.
In the actual code I use pcolormesh instead of scatter.
I hope I made myself clear. I had got ti working by creating the figure and ax1 each time the function is called, but then I added some more suff thath don't need to be plotted each time.
Thanks for taking the time to read!
A very limited answer is that you function should return fig not rh.
Also note that you don't need the lines with global, and plt.show()
import ipywidgets as widgets
from ipywidgets import interact
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1) = plt.subplots(ncols=1, subplot_kw=dict(projection='polar'))
RAD = np.array([0.85, 0.85, 0.85])
ANG = np.array([np.pi/2, np.pi*(2/3+1/2), np.pi*(1/2-2/3)])
c = ax1.scatter(ANG, RAD)
ax1.set_ylim([0, 1])
ax1.set_yticklabels([])
def h(rh):
RADp = np.array([rh, rh, rh])
ANGp = np.array([-np.pi/2, np.pi*(2/3-1/2), np.pi*(-1/2-2/3)])
cp = ax1.scatter(ANGp, RADp)
ax1.add_artist(cp)
# plt.show()
return fig
interact(h, rh = widgets.FloatSlider(min=0, max=1, step=0.001, value=1));
I say limited because I think you want to update rather than add point?
A version which is hopefully more in line with what you want
the key point being the use of set_offsets method to update the positions.
import ipywidgets as widgets
from ipywidgets import interact
import numpy as np
import matplotlib.pyplot as plt
fig, (ax1) = plt.subplots(ncols=1, subplot_kw=dict(projection='polar'))
RAD = np.array([0.85, 0.85, 0.85])
ANG = np.array([np.pi/2, np.pi*(2/3+1/2), np.pi*(1/2-2/3)])
c = ax1.scatter(ANG, RAD)
ax1.set_ylim([0, 1])
ax1.set_yticklabels([])
def h(rh):
new = [
[-np.pi/2, rh],
[np.pi*(2/3-1/2), rh],
[np.pi*(-1/2-2/3), rh],
]
c.set_offsets(new)
return fig
interact(h, rh = widgets.FloatSlider(min=0, max=1, step=0.001, value=1));

Python: Pickle.load function returns the correct 3d-scatter plot, but is not interactive anymore

this is my first question here so let me know if I should make any improvements regarding e.g. formulation of the question, code and so on.
So I am creating several 3-D Scatter Plots in Python and want to safe them for later re usage and comparability. I am using Qt5 as Graphics Backend in Spyder, which perfectly displays my interactive (so I can rotate over the axes and flip the plot) 3-D Scatter plot using the origin Code.
Now I am able to successfully save the created plot and also load it into a new script, which opens the Plot in Qt5 as well. But somehow the interactivity is gone, meaning I am not able to rotate over the axes and flip the plot anymore.
I was unable to find any guidance to that issue or find any person with a similar problem. Do you guys have any idea? I'll put the relevant part of my sample Code below:
""" First script """
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import pandas as pd
import pickle
testdf = pd.DataFrame({"X" : x, "Y" : y, "Z" : z}) #x and y are the criteria, z the values, stored as lists
# Create 3d scatter plot
fig = plt.figure(figsize=(12, 12))
ax = fig.add_subplot(111, projection="3d")
ax.scatter(x, y, z, c=z, marker="o")
ax.set_xlabel("Initial Notional Cluster")
ax.set_ylabel("Laufzeit in Month Cluster")
ax.set_zlabel("Vol. Weighted Margin")
plt.show()
# Save the figure object as binary file
file = open(r"Init_Lfz_VolWeightedMargin.pkl", "wb")
pickle.dump(fig, file)
file.close()
""" Second script """
import matplotlib.pyplot as plt
figx = pickle.load(open(r"Init_Lfz_VolWeightedMargin.pkl", "rb"))
plt.show()
Any idea, why the interactivity is gone? According to the pickle library and other usercases, this shall not happen.
Many thanks.

Alternatives to rendering in browser, using pio.renderers.default = ""

Got very happy when I learned the potential of applying plotly in my use of Python. I use PyCharm, and found out that I could depict numbers, figures, stats, etc using the above option. Yet I am bit confused. First, executing code including 'import plotly.io as pio' and on the following line 'pio.renderers.default = "browser"' it takes ages for the data and graphics to load, but almost only a split second to open the browser. Second, is there an alternative to the "browser"-choice, e.g. a choice that allowed fig.show() directly in the PyCharm console? - for jupyter I think the alternative is "notebook", but that is not PyCharm. If alternatives exist to pio, i.e. that prompt rendering of code execution in the console, I'd be all ears and eyes. Thx, in advance, for any advice.
import plotly.figure_factory as ff
import plotly.graph_objects as go
import numpy as np
import plotly.io as pio
pio.renderers.default = "browser"
## Create first figure
import plotly.io as pio
pio.renderers.default = "browser"
x1,y1 = np.meshgrid(np.arange(0, 2, .2), np.arange(0, 2, .2))
u1 = np.cos(x1)*y1
v1 = np.sin(x1)*y1
fig1 = ff.create_quiver(x1, y1, u1, v1, name='Quiver')
fig1.show()
## Create second figure
import plotly.io as pio
pio.renderers.default = "browser"
x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
Y, X = np.meshgrid(x, y)
u = -1 - X**2 + Y
v = 1 + X - Y**2
fig2 = ff.create_streamline(x, y, u, v, arrow_scale=.1, name='Steamline')
fig2.show()
Sometimes results are indeed rendered in a browser, mostly the browser stops loading and an utterly blank, white screen keeps staring at me. That is why I'd kind of fancied a rendering result as performed in matplotlib where graphics is shown in the console directly.
The official answer to your question is that you can use other renderers like “png” or “svg” as provided by Orca. If your figure is too complex, however, you may have trouble with any renderer, depending on your hardware setup.
More info here: https://plot.ly/python/renderers/

Basemap does not show plotted data (if plotted at all)

I've just recently started using basemap, and i've encountered a problem.
When i run :
import numpy as np
import matplotlib.pyplot as plt
import netCDF4 as nc
import glob
from mpl_toolkits.basemap import Basemap
import warnings #note that I did not include all of my code, so some imports may be unnecessary.
%matplotlib inline
datapath = "/somedirectory/www.ncei.noaa.gov/data/avhrr-land-leaf-area-index-and-fapar/access/2001" #I've downloaded the data from here as well, I've averaged over every month.
datafiles = glob.glob(datapath+"/"+"avg_LAI_fAPAR*.nc")
data = [None]*len(datafiles)
month = [None]*len(datafiles)
lats = [None] * len(datafiles)
lons = [None] * len(datafiles)
fAPAR =[None] * len(datafiles)
LAI =[None] * len(datafiles)
for number, file in enumerate(datafiles):
month[number] = file[-4:-2]
data[number] = nc.Dataset(file,format = 'NETCDF4')
lats[number] = data[number]["latitude"]
lons[number] = data[number]["longitude"]
fAPAR[number] = data[number]["FAPAR"]
LAI[number] = data[number]["LAI"]
m = Basemap(width=5000000,height=3500000,
resolution='l',\
lat_ts=40)
for k in range(1): #only do one loop, it takes a long time to run on my machine. Idea is that is should be able to loop through all months in 2001
print(k)
plt.figure()#figsize=(20,10))
lon, lat = np.meshgrid(lons[k], lats[k])
xi, yi = m(lon,lat)
cs = m.pcolor(xi,yi,np.squeeze(LAI[k][0])) #note that the first dimension [k] comes from the for-loop, the second [0] is the temporal part of the LAI (avereged out in a bash script).
m.drawcoastlines()
m.drawcountries()
cbar = m.colorbar(cs, location='bottom', pad="10%")
plt.title('LAI on {}'.format(month[k]))`
The plot comes out empty, so nothing plotted (only white space). The data is masked, but also if I unmasked the data (i.e. replace the masked data by a nan), the plot did not show anything. The np.nanmean(LAI[0]) is about 1, but the regular mean is about -90, as the fill value is -100.
The data seems to work with NCview in linux.
I work on python 3.6, with the latest packages installed. Does anyone know where the problem might be?
Thanks in advance!

Resources