Polynomial function in matplotlib displaying multiple lines [duplicate] - python

This question already has an answer here:
Too many lines and curves on the polynomial graph
(1 answer)
Closed 9 months ago.
I am experiencing the same issue that is asked in this question: Too many lines and curves on the polynomial graph
The solution for that issue seems to be sorting the points based on the x axis. In my case im pretty sure my data is already sorted as I am placing my x array into the plot like so:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
x = np.array([0,0,0,0,0,0,26,0,0,0,0,0,0,0,0,0,214,67,225,250,0,0,0,94,0,0,1366,137])
y = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,0,0,0,0,0,0,4,0])
fig3, ax3 = plt.subplots()
ax3.scatter(x, y)
ax3.plot(x, 0 + 0.004*x + 1.63e-06*(x**2), label='squared')
ax3.legend()
plt.show()
I would like to plot just the quadratic line:

Your example does indeed have unsorted data in the x axis, and the solution is just as in the question you linked:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
x = np.array([0,0,0,0,0,0,26,0,0,0,0,0,0,0,0,0,214,67,225,250,0,0,0,94,0,0,1366,137])
y = np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,5,0,0,0,0,0,0,4,0])
order = np.argsort(x)
fig3, ax3 = plt.subplots()
ax3.scatter(x[order], y[order])
ax3.plot(x[order], 0 + 0.004*x[order] + 1.63e-06*(x[order]**2), label='squared')
ax3.legend()
plt.show()

Related

Matplotlib: filling the area under the curve between two x-values [duplicate]

This question already has answers here:
fill_between with matplotlib and a where condition of two lists
(1 answer)
Matplotlib fill_between edge effect with `where` argument
(1 answer)
Fill between x and baseline x position in Matplotlib
(1 answer)
How to avoid gaps with matplotlib.fill_between and where
(1 answer)
Closed 1 year ago.
I'm plotting a blackbody curve and would like to fill in the area under the curve in the range of between 3 and 5 micron. However, I'm not sure how to use the fill_between or fill_betweenx plt commands here
import numpy as np
import matplotlib.pyplot as plt
from astropy import units as u
from astropy.modeling import models
from astropy.modeling.models import BlackBody
from astropy.visualization import quantity_support
bb = BlackBody(temperature=308.15*u.K)
wav = np.arange(1.0, 50.0) * u.micron
flux = bb(wav)
with quantity_support():
plt.figure()
plt.plot(wav, flux, lw=4.0)
plt.fill_between(wav,flux, min(flux), color = 'red')
plt.show()
This plots a fill under the whole curve, but only the 3-5micron part is desired to be filled.
example:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2, 100) # Sample data.
# Note that even in the OO-style, we use `.pyplot.figure` to create the figure.
fig, ax = plt.subplots() # Create a figure and an axes.
print(x)
ax.plot(x, x, label='linear') # Plot some data on the axes.
ax.set_xlabel('x label') # Add an x-label to the axes.
ax.set_ylabel('y label') # Add a y-label to the axes.
ax.set_title("Simple Plot") # Add a title to the axes.
ax.legend() # Add a legend.
plt.fill_between(x[:5],x[:5])
plt.show()
You can change the value 5 and play with it, you'll understand quickly. first parameter is Y positions , second is X positions.
fill_betweenx is just the same, but it will fill the other way around.
edit: As said in comments, it is better to use plt.fill_between(x,x, where = (x>0)&(x<0.2)). Both works, second solution is more explicit.

Question about mapping x-axis values in matplotlib [duplicate]

This question already has answers here:
Plot some numbers in x axis
(3 answers)
plot with custom text for x axis points
(3 answers)
Force python axis to show specific numbers
(2 answers)
Closed 1 year ago.
I am starting to use the matplotlib library to generate simple graphs. In one of my tests something happens to me that does not allow me to obtain the graph that I expect. Coming to the point, I have two value arrays (circle and g) and I would like to join each of their values. The problem comes when I input the x-axis values. I would like only the values of my array g to be on the x axis, but the following happens:
In my code I have the following:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
circle = [0.002,0.013,0.035]
g = [5,25,50]
ax.scatter(g[0], circle[0], color = 'g', marker = "o")
x = np.array([0,1,2,3])
my_xticks = [0,5,25,50]
plt.xticks(x, my_xticks)
plt.show()
Could someone help me fix this?
The problem was that when calling plt.xticks(), you passed [0, 1, 2, 3] as the x-tick values, and you passed the tick values you really wanted as the tick labels. Instead, pass the tick values you want as the first argument, and omit the second argument. The tick labels will be strings of the tick values by default.
import matplotlib.pyplot as plt
circle = [0.002, 0.013, 0.035]
g = [5, 25, 50]
my_xticks = [0] + g
fig, ax = plt.subplots()
ax.scatter(g, circle, color='g', marker='o')
plt.xticks(my_xticks)
plt.show()

How to represent a single point on a matlplotlib plot [duplicate]

This question already has answers here:
How to plot one single data point?
(4 answers)
Closed 4 years ago.
I have a graph which represents the sentiments of the values in a column of pandas dataframe. Given a sentence, I want to highlight the corresponding sentiment value on the graph/plot. I am looking for an output similar to the image below:
You can use pyplot.scatter and pass single values in for x and y. Here's an example:
from matplotlib import pyplot as plt
import numpy as np
fig = plt.figure()
x_data = np.linspace(0,3.5,100)
y_data = [-x * (x - 3.2) for x in x_data]
plt.plot(x_data, y_data, color='#0000ff', zorder=0)
x_point = x_data[20]
y_point = y_data[20]
plt.scatter(x_point, y_point, color='#ff0000', zorder=1)
Produces:

How to plot y=1/x as a single graph [duplicate]

This question already has answers here:
Omit joining lines in matplotlib plot e.g. y = tan(x)
(4 answers)
Closed 5 years ago.
Is there an easy way to plot a function which tends to infinity in the positive and negative as a single plot, without the plot joining both ends of the positive and negative?
For example, plotting y=1/x using this code gives the resulting plot:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return 1/x
fx_name = r'$f(x)=\frac{1}{x}$'
x=np.setdiff1d(np.linspace(-10,10,100),[0]) #to remove the zero
y=f(x)
plt.plot(x, y, label=fx_name)
plt.legend(loc='upper left')
plt.show()
But I would like this output, which I achieve by plotting two separate domains:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return 1/x
fx_name = r'$f(x)=\frac{1}{x}$'
xfn=np.setdiff1d(np.linspace(-10,0,100),[0])
xfp=np.setdiff1d(np.linspace(0,10,100),[0])
yfn=f(xfn)
yfp=f(xfp)
yf = plt.plot(xfn, yfn, label=fx_name)
plt.plot(xfp, yfp, color=yf[0].get_color())
plt.legend(loc='upper left')
plt.show()
Is there are short-cut?
Many thanks.
Solution
Include zero in the domain array, and suppress the divide by zero. This forces one element of the returned co-domain array as "inf", and "inf" is not plotted.
import numpy as np
import matplotlib.pyplot as plt
def f(x):
with np.errstate(divide='ignore', invalid='ignore'):
return 1/x
fx_name = r'$f(x)=\frac{1}{x}$'
x=np.linspace(-10,10,101)
y=f(x)
plt.plot(x, y, label=fx_name)
plt.legend(loc='upper left')
plt.show()
I prefer this method since it avoids manual manipulation of the array, and can be easily reused for other functions which share the same domain (ex. y=1/(x+2)). Thank you all for contributions.
Actually you want to include x = 0 because this results in y = nan, forming a gap in the plot.
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return 1/x
fx_name = r'$f(x)=\frac{1}{x}$'
# using 101 steps results in in array including the value 0
x=np.linspace(-10,10,101)
# f(0) = nan -> a nan value creates a gap
y=f(x)
plt.plot(x, y, label=fx_name)
plt.legend(loc='upper left')
plt.show()
Not necessary easier as your workaround, but you could insert a 'nan' element at the index where the sign flips, for example:
idx = np.argmax(np.diff(np.sign(y)))+1
x = np.insert(x, idx, np.nan)
y = np.insert(y, idx, np.nan)
The 'nan' causes Matplotlib to interrupt the line.
based on Rutger Kassies ideas:
n_points = 100
x=np.setdiff1d(np.linspace(-10,10,n_points),[0]) #to remove the zero
y=f(x)
y[n_points//2-1:n_points//2+1] = np.nan
use your original plot an set the points around 0 to np.nan. that way too many points get set to None but it's symmetric.
you could also setup your linspace to includ 0 such that f(x) = np.nan: n_points = 101. (this answer and 2 comments stated that right before i did... please credit there).

Filling region between curve and x-axis in Python using Matplotlib

I am trying to simply fill the area under the curve of a plot in Python using MatPlotLib.
Here is my SSCCE:
import json
import pprint
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791]
x = np.arange(len(y))
fig2, ax2 = plt.subplots()
ax2.fill(x, y)
plt.savefig('picForWeb.png')
plt.show()
The attached picture shows the output produced.
Does anyone know why Python is not filling the entire area in between the x-axis and the curve?
I've done Google and StackOverflow searches, but could not find a similar example. Intuitively it seems that it should fill the entire area under the curve.
I usually use the fill_between function for these kinds of plots. Try something like this instead:
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791]
x = np.arange(len(y))
fig, (ax1) = plt.subplots(1,1);
ax1.fill_between(x, 0, y)
plt.show()
See more examples here.
If you want to use this on a pd.DataFrame use this:
df.abs().interpolate().plot.area(grid=1, linewidth=0.5)
interpolate() is optional.
plt.fill assumes that you have a closed shape to fill - interestingly if you add a final 0 to your data you get a much more sensible looking plot.
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791,0]
x = np.arange(len(y))
fig2, ax2 = plt.subplots()
ax2.fill(x, y)
plt.savefig('picForWeb.png')
plt.show()
Results in:
Hope this helps to explain your odd plot.

Categories