I am wondering if it is maybe possible to plot the output of numpy.histogram2d() using matplotlib.pyplot.hist2d? In the one-dimensional case, this can be done by using:
counts, bins = np.histogram(something, bins=no_bins, range=(range_min, range_max))
plt.hist(bins[:-1], bins, weights=counts)
Is there a similar solution for the two-dimensional case? I do not want to plot the 2d histo with the methods suggested on https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram2d.html
The idea behind this is that I would like to apply some corrections to the inital histogram (i.e. bin-by-bin background subtraction using data from another 2d histogram) and then plot the corrected histogram.
Many thanks in advance!
Plotting 2d histograms is typically done with imshow(). If you're used to ROOT or some other plotting libraries, be especially careful what argument you give for origin and extent.
The following solution works as expected:
counts_bkg, bins_x_bkg, bins_y_bkg = np.histogram2d(x_bkg, y_bkg, bins=(x_bins, ybins))
counts, bins_x, bins_y = np.histogram2d(x, y, bins=(x_bins, y_bins))
diff = counts - counts_bkg
diffT = diff.T
fig, ax = plt.subplots(1)
pc = ax.pcolorfast(bins_x, bins_y, diffT)
plt.show()
In the docs, you can find three examples of how to plot the output from np.histogram2d() using the matplotlib functions imshow, pcolormesh and NonUniformImage.
I googled my way here. I am going to write here what worked for me, just in case, some else finds themselves in similar situtation.
I was looking at the source code of pyplot, where I found reference to axes class. The hist2d funtion is actually defined in 'matplotlib/axes/_axes.py'.
There I found hist2d calls np.histogram2s and then uses the xedges, yedges and bins in plt.pcolormesh as follow:
pc = self.pcolormesh(xedges, yedges, h.T, **kwargs)
Remember there is no option to use keywords 'Range', 'density' and 'bins' in pcolormesh but these are taken into account by the np.histogram2d function.
TL;DR: Using pcolormesh is the simplest way for plotting 2D histogram from the output of np.histogram2d.
Related
I have seen two methods online, but after trying the two methods you'd think the plots should look the same, but they do not.
Method1:
n, bins, patches = plt.hist(SP[0], 30, facecolor='green', alpha=1, histtype='stepfilled')
Method2:
counts, bins = np.histogram(SP[0])
plt.hist(bins[:-1], bins=30, weights=counts)
The two methods do completely different things. Method1 is the correct one. plt.hist() calculates the histogram of its first argument and plots the result.
There simply is a mistake in method2. You first calculate your histogram via np.histogram() and then plot the results. But you don't use plt.hist() in the second step. If you do so, you will plot the histogram of the bins of the resulting histogram of the function call before. Instead, you just use plt.plot() or plt.step(). I would suggest you use:
counts, bins = np.histogram(SP[0], bins=30)
plt.step(bins[:-1], counts, where='post')
I am currently taking a Matplotlib class. I was given an image to create the image as a 3D subplot 4 times at 4 different angles. It's a linear plot. As the data changes the plots change colors. As it's an image, I'm not certain where the actual changes start. I don't want an exact answer, just an explanation of how this would work. I have found many methods for doing this for a small list but this has 75 data points and I can't seem to do it without adding 75 entries.
I've also tried to understand cmap but I am confused on it as well.
Also, it needs to done without Seaborn.
This is part of the photo.
I am finding your question a little bit hard to understand. What I think you need is a function to map the input x/y argument onto a colour in your chosen colour map. See the below example:
import numpy as np
import matplotlib.pyplot
def number_to_colour(number, total_number):
return plt.cm.rainbow(np.linspace(0,1.,total_number))[list(number)]
x = np.arange(12)
y = x*-3.
z = x
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c=number_to_colour(x, len(x)))
plt.show()
plt.cm.rainbow(np.linspace(0,1.,total_number)) creates an array of colours of length total_number evenly spaced spaced across the colour map (in this case rainbow). Modifying the indexing of this array (or changing np.linspace to another function with the desired scaling), should give you the colour scaling that you need.
I need to plot changing molecule numbers against time. But I'm also trying to investigate the effects of parallel processing so I'm trying to avoid writing to global variables. At the moment I have the following two numpy arrays tao_all, contains all the time points to be plotted on the x-axis and popul_num_all which contains the changing molecule numbers to be plotted on the y-axis.
The current code I've got for plotting is as follows:
for i, label in enumerate(['Enzyme', 'Substrate', 'Enzyme-Substrate complex', 'Product']):
figure1 = plt.plot(tao_all, popul_num_all[:, i], label=label)
plt.legend()
plt.tight_layout()
plt.show()
I need to encapsulate this in a function that takes the above arrays as the input and returns the graph. I've read a couple of other posts on here that say I should write my results to an axis and return the axis? But I can't quite get my head around applying that to my problem?
Cheers
def plot_func(x, y):
fig,ax = plt.subplots()
ax.plot(x, y)
return fig
Usage:
fig = plot_func([1,2], [3,4])
Alternatively you may want to return ax. For details about Figure and Axes see the docs. You can get the axes array from the figure by fig.axes and the figure from the axes by ax.get_figure().
In addition to above answer, I can suggest you to use matplotlib animation.FuncAnimation method if you are working with the time series and want to make your visualization better.
You can find the details here https://matplotlib.org/api/_as_gen/matplotlib.animation.FuncAnimation.html
I have a Data Frame df with two columns 'Egy' and 'fx' that I plot in this way:
plot_1 = df_data.plot(x="Egy", y="fx", color="red", ax=ax1, linewidth=0.85)
plot_1.set_xscale('log')
plt.show()
But then I want to smooth this curve using spline like this:
from scipy.interpolate import spline
import numpy as np
x_new = np.linspace(df_data['Egy'].min(), df_data['Egy'].max(),500)
f = spline(df_data['Egy'], df_data['fx'],x_new)
plot_1 = ax1.plot(x_new, f, color="black", linewidth=0.85)
plot_1.set_xscale('log')
plt.show()
And the plot I get is this (forget about the scatter blue points).
There are a lot of "peaks" in the smooth curve, mainly at lower x. How Can I smooth this curve properly?
When I consider the "busybear" suggestion of use np.logspace instead of np.linspace I get the following picture, which is not very satisfactory either.
You have your x values linearly scaled with np.linspace but your plot is log scaled. You could try np.geomspace for your x values or plot without the log scale.
Using spline will only work well for functions that are already smooth. What you need is to regularize the data and then interpolate afterwards. This will help to smooth out the bumps. Regularization is an advanced topic, and it would not be appropriate to discuss it in detail here.
Update: for regularization using machine learning, you might look into the scikit library for Python.
I have the code below:
fig, ax = pyplot.subplots()
graph = ax.pcolorfast(data, cmap='viridis', vmin = min, vmax = max)
pyplot.colorbar(graph)
pyplot.show()
and it plots what I wanted, however it is sideways. Is there a good way of rotating it -90 or 270 degrees? I have tried a.T, which returns the original plot. I have also tried ndimage.rotate(graph, -90|270), ndimage.interpolation.rotate(graph, -90|270), and numpy.rot90(data,3). The first two return errors for invalid rotation planes and the second appears to shove the graph off the edge, losing a majority of my data points.
If anyone has some thoughts, I would be very grateful. Even if it's that I put in the wrong arguments. I am at a loss here.
Is a supposed to be equal to data in your example? Tried your code with a random 2D array, and np.transpose(a) as well as a.T seem to properly rotate the figure, as opposed to what you indicate here ('returns the original plot'). If this is not the case for you, I think we need more information.