this seems a simple question but I have tried it for a really long time.
I got a 1d array data(named 'hightemp_unlocked', after I found the peaks(an array of location where the peaks are located) of it, I wanted to mark the peaks on the plot.
import matplotlib
from matplotlib import pyplot as plt
.......
plt.plot([x for x in range(len(hightemp_unlocked))],hightemp_unlocked,label='200 mk db ramp')
plt.scatter(peaks, hightemp_unlocked[x in peaks], marker='x', color='y', s=40)
for some reason, it keeps telling me that x, y must be the same size
it shows:
File "period.py", line 86, in <module>
plt.scatter(peaks, hightemp_unlocked[x in peaks], marker='x', color='y', s=40)
File "/usr/local/lib/python2.6/dist-packages/matplotlib/pyplot.py", line 2548, in scatter
ret = ax.scatter(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, faceted, verts, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/matplotlib/axes.py", line 5738, in scatter
raise ValueError("x and y must be the same size")
I don't think hightemp_unlocked[x in peaks] is what you want. Here x in peaks reads as the conditional statement "is x in peaks?" and will return True or False depending on what was last stored in x. When parsing hightemp_unlocked[x in peaks], True or False is interpreted as 0 or 1, which returns only the first or second element of hightemp_unlocked. This explains the array size error.
If peaks is an array of indexes, then simply hightemp_unlocked[peaks] will return the corresponding values.
You are almost on the right track, but hightemp_unlocked[x in peaks] is not what you are looking for. How about something like:
from matplotlib import pyplot as plt
# dummy temperatures
temps = [10, 11, 14, 12, 10, 8, 5, 7, 10, 12, 15, 13, 12, 11, 10]
# list of x-values for plotting
xvals = list(range(len(temps)))
# say our peaks are at indices 2 and 10 (temps of 14 and 15)
peak_idx = [2, 10]
# make a new list of just the peak temp values
peak_temps = [temps[i] for i in peak_idx]
# repeat for x-values
peak_xvals = [xvals[i] for i in peak_idx]
# now we can plot the temps
plt.plot(xvals, temps)
# and add the scatter points for the peak values
plt.scatter(peak_xvals, peak_temps)
Related
I have a vector x with length N=n**2=625 which I simply plot with imshow by reshaping into a matrix, which is essentially a 2D topographical map.
plt.imshow(x.reshape((n,n)),cmap="magma",origin="lower")
I also have a given connected path with the some indices of the vector x, e.g
path = np.array([1, 2, 27, 28, 54,55,56,81,106,131])
I want to display this on top of the heatmap with lines, to indicate the path. Any ideas on how I can to this?
IIUC, you can use numpy.unravel_index to convert your coordinates:
import matplotlib.pyplot as plt
n=25
x = np.arange(n**2)
ax = plt.imshow(x.reshape((n,n)),cmap="magma",origin="lower", alpha=0.2)
X, Y = np.unravel_index(np.array([1, 2, 27, 28, 54,55,56,81,106,131]), (n, n))
plt.plot(Y, X)
Example:
I know that when you usually plot a histogram you have an array of values and intervals.
But if I have intervals and the number of values that are in those intervals, how can I plot the histogram?
I have something that looks like this:
amounts = np.array([23, 7, 18, 5])
and my interval is from 0 to 4 with step 1,
so on interval [0,1] there are 23 values and so on.
You could probably try matplotlib.pyplot.stairs for this.
import matplotlib.pyplot as plt
import numpy as np
amounts = np.array([23, 7, 18, 5])
plt.stairs(amounts, range(5))
plt.show()
Please mark it as solved if this helps.
I find it easier to just simulate some data having the desired distribution, and then use plt.hist to plot the histogram.
Here is am example. Hopefully it will be helpful!
import numpy as np
import matplotlib.pyplot as plt
amounts = np.array([23, 7, 18, 5])
bin_edges = np.arange(5)
bin_centres = (bin_edges[1:] + bin_edges[:-1]) / 2
# fake some data having the desired distribution
data = [[bc] * amount for bc, amount in zip(bin_centres, amounts)]
data = np.concatenate(data)
hist = plt.hist(data, bins=bin_edges, histtype='step')[0]
plt.show()
# the plotted distribution is consistent with amounts
assert np.allclose(hist, amounts)
If you already know the values, then the histogram just becomes a bar plot.
amounts = np.array([23, 7, 18, 5])
interval = np.arange(5)
midvals = (interval + 0.5)[0:len(vals)-1] # 0.5, 1.5, 2.5, 3.5
plt.bar(midvals,
amounts)
plt.xticks(interval) # Shows the interval ranges rather than the centers of the bars
plt.show()
If the gap between the bars looks to wide, you can change the width of the bars by passing in a width (as a fraction of 1 - default is 0.8) argument to plt.bar().
I'm using Python and matplotlib.
I have a lot of Points, generated with arrays.
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=Groesse_cm/2.54)
ax.set_title(title)
ax.set_xlabel(xlabel) # Beschriftung X-Achse
ax.set_ylabel(ylabel) # Beschriftung Y-Achse
ax.plot(xWerte, yWerte, 'ro', label=kurveName)
ax.plot(xWerte, y2Werte, 'bo', label=kurveName2)
plt.show()
So I have the arrayX for x Values and the arrayYmax for Y Values (red) and arrayYmin for Y Values (blue). I can't give you my arrays, couse that is much too complicated.
My question is:
How can I get a spline/fit like in the upper picture? I do not know the function of my fited points, so I have just Points with [x / y] Values. So i don't wann connect the points i wanna have a fit. So yeah I say fit to this :D
Here is an example i don't wanna have:
The code for this is:
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=Groesse_cm/2.54)
degree = 7
np.poly1d(np.polyfit(arrayX,arrayYmax,degree))
ax.plot(arrayX, arrayYmax, 'r')
np.poly1d(np.polyfit(arrayX,arrayYmin,degree))
ax.plot(arrayX, arrayYmin, 'b')
#Punkte
ax.plot(arrayX, arrayYmin, 'bo')
ax.plot(arrayX, arrayYmax, 'ro')
plt.show()
you're pretty close, you just need to use the polynomial model you're estimating/fitting.
start with pulling in packages and defining your data:
import numpy as np
import matplotlib.pyplot as plt
arr_x = [-0.8, 2.2, 5.2, 8.2, 11.2, 14.2, 17.2]
arr_y_min = [65, 165, 198, 183, 202, 175, 97]
arr_y_max = [618, 620, 545, 626, 557, 626, 555]
then we estimate the polynomial fit, as you were doing, but saving the result into a variable that we can use later:
poly_min = np.poly1d(np.polyfit(arr_x, arr_y_min, 2))
poly_max = np.poly1d(np.polyfit(arr_x, arr_y_max, 1))
next we plot the data:
plt.plot(arr_x, arr_y_min, 'bo:')
plt.plot(arr_x, arr_y_max, 'ro:')
next we use the polynomial fit from above to plot estimated value at a set of sampled points:
poly_x = np.linspace(-1, 18, 101)
plt.plot(poly_x, poly_min(poly_x), 'b')
plt.plot(poly_x, poly_max(poly_x), 'r')
giving us:
note that I'm using much lower degree polynomials (1 and 2) than you (7). a seven degree polynomial is certainly overfitting this small amount of data, and these look like a reasonable fits
My question is about a readability issue with a plot. I read several similar questions on StackOverflow but none of them solved completely the problem.
I have a txt file with 100 abscissa and ordinate values.
I want to plot them but on the x-axes, I want to be shown only specified tick values.
E.g: the 1st,2nd,3rd,4th,5th,44th,88th, and the 99th point. It is only something that I want for better readability because I want to plot all the points anyway.
What I tried is:
import matplotlib.pyplot as plt
import numpy as np
plt.xlabel("Values")
plt.ylabel("Percentage")
for i in range(99):
try:
filename = "Folder_Name/foo_%d.txt" % i
filevals = np.loadtxt(filename, usecols=1)
idx = [1, 2, 3, 4, 5, 44, 88, 99]
y = [filevals[k]*100 for k in idx]
plt.plot(range(len(idx)), y, 'o-', label="values_foo_%s" % i)
plt.xticks(range(len(idx)), idx)
except IOError or IndexError:
break
plt.legend(loc=4)
plt.grid(True)
plt.tight_layout()
plt.savefig("plot_test.pdf")
plt.close()
As a result, of course, the graph obtained plots only that values ignoring the other points and, as a consequence, the distance between the 5th and the 44th points is the same as it is between the 4th and the 5th.
Just write: plt.xtick([0, 1, 2, 3, 4, 43, 87, 98])
Also, don't forget that a list index begins with 0.
I have a three-dimensional array.
The first dimension has 4 elements.
The second dimension has 10 elements.
The third dimension has 5 elements.
I want to plot the contents of this array as follows.
Each element of the first dimension gets its own graph (four graphs on the page)
The values of the second dimension correspond to the y values of the graphs. (there are 10 lines on each graph)
The values of the third dimension correspond to the x values of the graphs (each of the 10 lines has 5 x values)
I'm pretty new to python, and even newer to graphing.
I figured out how to correctly load my array with the data...and I'm not even trying to get the 'four graphs on one page' aspect working.
For now I just want one graph to work correctly.
Here's what I have so far (once my array is set up, and I've correctly loaded my arrays. Right now the graph shows up, but it's blank, and the x-axis includes negative values. None of my data is negative)
for n in range(1):
for m in range(10):
for o in range(5):
plt.plot(quadnumcounts[n][m][o])
plt.xlabel("Trials")
plt.ylabel("Frequency")
plt.show()
Any help would be really appreciated!
Edit. Further clarification. Let's say my array is loaded as follows:
myarray[0][1][0] = 22
myarray[0][1][1] = 10
myarray[0][1][2] = 15
myarray[0][1][3] = 25
myarray[0][1][4] = 13
I want there to be a line, with the y values 22, 10, 15, 25, 13, and the x values 1, 2, 3, 4, 5 (since it's 0 indexed, I can just +1 before printing the label)
Then, let's say I have
myarray[0][2][0] = 10
myarray[0][2][1] = 17
myarray[0][2][2] = 9
myarray[0][2][3] = 12
myarray[0][2][4] = 3
I want that to be another line, following the same rules as the first.
Here's how to make the 4 plots with 10 lines in each.
import matplotlib.pyplot as plt
for i, fig_data in enumerate(quadnumcounts):
# Set current figure to the i'th subplot in the 2x2 grid
plt.subplot(2, 2, i + 1)
# Set axis labels for current figure
plt.xlabel('Trials')
plt.ylabel('Frequency')
for line_data in fig_data:
# Plot a single line
xs = [i + 1 for i in range(len(line_data))]
ys = line_data
plt.plot(xs, ys)
# Now that we have created all plots, show the result
plt.show()
Here is the example of creating subplots of your data. You have not provided the dataset so I used x to be an angle from 0 to 360 degrees and the y to be the trigonemetric functions of x (sine and cosine).
Code example:
import numpy as np
import pylab as plt
x = np.arange(0, 361) # 0 to 360 degrees
y = []
y.append(1*np.sin(x*np.pi/180.0))
y.append(2*np.sin(x*np.pi/180.0))
y.append(1*np.cos(x*np.pi/180.0))
y.append(2*np.cos(x*np.pi/180.0))
z = [[x, y[0]], [x, y[1]], [x, y[2]], [x, y[3]]] # 3-dimensional array
# plot graphs
for count, (x_data, y_data) in enumerate(z):
plt.subplot(2, 2, count + 1)
plt.plot(x_data, y_data)
plt.xlabel('Angle')
plt.ylabel('Amplitude')
plt.grid(True)
plt.show()
Output:
UPDATE:
Using the sample date you provided in your update, you could proceed as follows:
import numpy as np
import pylab as plt
y1 = (10, 17, 9, 12, 3)
y2 = (22, 10, 15, 25, 13)
y3 = tuple(reversed(y1)) # generated for explanation
y4 = tuple(reversed(y2)) # generated for explanation
mydata = [y1, y2, y3, y4]
# plot graphs
for count, y_data in enumerate(mydata):
x_data = range(1, len(y_data) + 1)
print x_data
print y_data
plt.subplot(2, 2, count + 1)
plt.plot(x_data, y_data, '-*')
plt.xlabel('Trials')
plt.ylabel('Frequency')
plt.grid(True)
plt.show()
Note that the dimensions are slightly different from yours. Here they are such that mydata[0][0] == 10, mydata[1][3] == 25 etc. The output is show below: