I want to make a demonstration for the approximation of an integral of a continuous function with piecewise constant step functions.
The resulting plot should look something like this:
I have the piece constant function, my problem is that I don't know how to plot it since the typical candidates don't seem to work:
It looks similar to a histogram, but is generated very differently.
And from what I have seen bar-charts don't align to the number line.
The plt.step() method on the other hand does not include the bins/bars; using it I got this so far:
with this code
kwargs = dict(drawstyle = 'steps-mid')
plt.plot(times, f(times), '-')
plt.plot(times, fitted_values, **kwargs)
Is there a dedicated function, or some kwargs argument that I overlooked, that can plot what I need here?
Edit:
Thank you for the answer #Stef ! I just tried this solution and recognized an issue with a bar-plot here.
plt generates a bar for every value in the times array. Now I get this result:
You can use bar with the align parameter:
import numpy as np
x = np.linspace(0, 1, 11)
y = x**2 + 1
plt.plot(x, y, 'r-')
plt.bar(x, y, width=0.1, align='edge', fc='lightgreen', ec='k')
plt.xlim(0, 1)
Related
I want to plot points on the interval x in [0, 4]. My function performs something interesting for very small values, so I would like to create a non-linear scale that would use more space for smaller values of x. Logarithmic scale would be a great solution, but the problem is that my x-axis must include 0, which is not part of logarithmic axis.
So I considered using a power scale. After some googling I came across the following solution.
def stratify(ax, power=2):
f = lambda x: (x + 1)**(1 / power)
f_inv = lambda y: y**power - 1
ax.set_xscale('function', functions=(f, f_inv))
x = np.linspace(0, 4, 100)
y = np.sqrt(x)
fig, ax = plt.subplots()
ax.plot(x, y)
stratify(ax, 2)
plt.show()
The function stratify changes the x-scale of the plot to the square root function. This looks kind of correct. Below is a minimal example plot corresponding to the above code (not actual data).
I would like to have control over the nonlinearity in the x-scale, that is why I have introduced the power parameter. However, when I change the power parameter to value different from 2, the plot does not change at all. This is very surprising for me. I would appreciate if somebody could advise me how I can control the extent of non-linearity in x-axis. If possible, I would like it even more non-linear, making the interval [0, 0.5] take half of the plot.
EDIT While the current solution by #Thomas works as intended, the plotting routine throws a lot of errors when one attempts to do anything with it. For example, I would like to insert extra ticks, as the original only has integer ticks for whatever reason. Inserting extra ticks via ax.set_xticks(ax.get_xticks() + [0.5]) results in an error posx and posy should be finite values. What is this error, and how can it be bypassed?
For me, there's a change when switching from power=2 to power=10. Just be careful to edit it at the right position, i.e. when calling stratify=X.
Here's power=2:
Here's power=10:
However, here's another suggestion that is slightly more aggressive:
import numpy as np
import matplotlib.pyplot as plt
def stratify(ax, scale=1):
f = lambda x: np.log(x / scale + 1)
f_inv = lambda y: scale * (np.exp(y) - 1)
ax.set_xscale('function', functions=(f, f_inv))
x = np.linspace(0, 4, 100)
y = np.sqrt(x)
fig, axs = plt.subplots(1, 3)
for i, scale in enumerate([10,1,0.1]):
ax = axs[i]
ax.set_title(f'Scale={scale}')
ax.plot(x, y)
stratify(ax, scale=scale)
plt.show()
Resulting in
Another option are zoom regions.
import numpy as np
import matplotlib.pyplot as plt
def logistic (n,r,initialTerm) :
xlogistic = np.zeros((n,1))
ylogistic = np.zeros((n,1))
rr = r * np.ones((n,1))
ylogistic[0] = initialTerm
for i in range(1,n,1):
ylogistic[i] = r*ylogistic[i-1]*(1-ylogistic[i-1])
#print(ylogistic[i])
xlogistic[0] = ylogistic[100]
for i in range(1,n,1):
xlogistic[i] = r*xlogistic[i-1]*(1-xlogistic[i-1])
#print(xlogistic[i])
plt.plot(rr,xlogistic)
return (xlogistic[i])
"""
Testing the Functions
"""
theLogisticMap = logistic(1000,3.9,0.5)
As the question is not clear, I'm assuming you are asking how to show the graph.
after plotting using plt.plot and performing other graph related commands, you can use plt.show() to show the plot at the line of code you want it to be shown.
Also, you should never loop within numpy indices, it takes a long time,
try your code using a large number that would take time to process
then modify it by converting the values to a normal python list :
xlogistic = np.zeros((n,1))
ylogistic = np.zeros((n,1))
rr = r * np.ones((n,1))
xlogistic = list(xlogistic)
ylogistic = list(ylogistic)
rr = list(rr)
you'll find it way faster.
=============================
since you are new to python, here are some commands you can make use of before showing the graph:
plt.plot(x, y, ’r--’)
third argument for colour (b,w,g,....) and/or style (--, -, ..). you can use one or both.
you can also plot two functions on the same graph. with or without styling
plt.plot(rr,xlogistic,’r’, x , y, ’--’)
to mark a specific point or points (same logic as plotting two functions) just plot a specific point... preferably with a good style for a point like *, unlike --
plt.plot(x[0], y[0], ’ro’, x[-1], y[-1], ’r*’)
some examples to finish off your graphs:
plt.xlabel('t (s)')
plt.ylabel('y (m)')
plt.legend(['Line1']) #one legend
plt.legend([’t**2’, ’e**t’]) #multiple legends
plt.grid('on')
plt.axis([x1, x2, y1, y2]) # axes limits
plt.title(’Title’)
I use the functions plot() and hist() from pyplot (without any color definition) to generate the following graphic:
There will be even more data sets included. That's why I want to use the same color for fit curve and the related histogram, to keep it somewhat distinguishable.
I couldn't find anything related to it.
to make sure the plot and the histogram have the same colour, my suggestion is that you fix the colour for the plot and for the best fit line.
If you look at the example here http://matplotlib.org/1.2.1/examples/pylab_examples/histogram_demo.html
and then at the python documentation for pyplot http://matplotlib.org/1.2.1/api/pyplot_api.html?highlight=hist#matplotlib.pyplot.hist
the matplotlib.pyplot.hist method has a kwarg color that allows you to choose the colour you want for the histogram. In the example they set facecolor='green'
Then for the best fit line, you can choose to plot it in the same colour. I would need to see the code to give more precise indications. However if we go back to the example here the line properties are set:
l = plt.plot(bins, y, 'r--', linewidth=1)
so if we wanted the fit line to be green like the rest of the histogram we would use:
l = plt.plot(bins, y, 'r--', linewidth=1, color = 'green')
Hope this helps, can't give you more specific tips if you don't post any lines of code.
I found a solution using
plt.gca().set_color_cycle(None)
Thanks to Reset color cycle in Matplotlib
The following code should work out of the box to complete my question regarding gaussian fit with same color as bars of histogram
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
import numpy as np
list_of_lists = []
for i in range(2):
list = np.random.normal(0, 1, 100)
list = list.tolist()
list_of_lists.append(list)
plt.figure()
plt.hist(list_of_lists, bins = 10, normed=True)
numb_lists = len(list_of_lists)
plt.gca().set_color_cycle(None)
for i in range(0, numb_lists):
list = list_of_lists[i][:]
mean = np.mean(list)
variance = np.var(list)
sigma = np.sqrt(variance)
x = np.linspace(min(list), max(list), 100)
plt.plot(x, mlab.normpdf(x, mean, sigma))
I'm trying to plot the contour map of a given function f(x,y), but since the functions output scales really fast, I'm losing a lot of information for lower values of x and y. I found on the forums to work that out using vmax=vmax, it actually worked, but only when plotted for a specific limit of x and y and levels of the colormap.
Say I have this plot:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
u = np.linspace(-2,2,1000)
x,y = np.meshgrid(u,u)
z = (1-x)**2+100*(y-x**2)**2
cont = plt.contour(x,y,z,500,colors='black',linewidths=.3)
cont = plt.contourf(x,y,z,500,cmap="jet",vmax=100)
plt.colorbar(cont)
plt.show
I want to uncover whats beyond the axis limits keeping the same scale, but if I change de x and y limits to -3 and 3 I get:
See how I lost most of my levels since my max value for the function at these limits are much higher. A work around to this problem is to increase the levels to 1000, but that takes a lot of computational time.
Is there a way to plot only the contour levels that I need? That is, between 0 and 100.
An example of a desired output would be:
With the white space being the continuation of the plot without resizing the levels.
The code I'm using is the one given after the first image.
There are a few possible ideas here. The one I very much prefer is a logarithmic representation of the data. An example would be
from matplotlib import ticker
fig = plt.figure(1)
cont1 = plt.contourf(x,y,z,cmap="jet",locator=ticker.LogLocator(numticks=10))
plt.colorbar(cont1)
plt.show()
fig = plt.figure(2)
cont2 = plt.contourf(x,y,np.log10(z),100,cmap="jet")
plt.colorbar(cont2)
plt.show()
The first example uses matplotlibs LogLocator functions. The second one just directly computes the logarithm of the data and plots that normally.
The third example just caps all data above 100.
fig = plt.figure(3)
zcapped = z.copy()
zcapped[zcapped>100]=100
cont3 = plt.contourf(x,y,zcapped,100,cmap="jet")
cbar = plt.colorbar(cont3)
plt.show()
I am trying to plot the solutions of a minimization problem,
'X, Y = meshgrid(gammas, psis)'
gammas and psis are my 2 axes,
'mplot3d(X, Y, x)'
x is the solution of my problem,
While executing my script : name 'mplot3d' is not defined......
import pylab
def scatterme(x, y, z):
pylab.figure()
imi = pylab.scatter(x, y, c = z, edgecolor = "none")
pylab.colorbar(imi)
pylab.show()
In this case, my x and y are what for you would be X.flatten() and Y.flatten() and the z would be your x.flatten(). This code also works if your data does not come from something square, so if you just want to see what something looks like, if you have a lot of x and y values, and for each one you have a z, this shows you what you want as well.
Note: this is not a 3D plot, but i (personnal opinion) feel that a scatterplot in which the z-dimension is your colorbar seems to show much more what you need to know, compared to a 3D plot that you have to rotate around all the time, to be able to see at the angle that might show you something you want to know
Edit:
for the full code, that you can just copypaste (put this after the first piece in my post)
import numpy
X,Y = meshgrid(gammas, psis)
scatterme(X.flatten(), Y.flatten(), x.flatten())