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.
Related
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.
Firstly, a big thanks to everyone who responds to these questions. I've made it this far without having to ask a question because I find that someone before me has inevitably encountered the same issue.
However, I find myself with a question that I've not been able to locate. I would like to plot a 2D array within imshow that started off with a linear Y-axis, which I have had to offset and adjust and is now non-linear after a certain point. Is this possible?
see below for a chart and example.
The orange line is the original Y-axis step which has a linear and regular step.
The blue line has been corrected with an offset and a varying step change towards the end. As seen it is linear up to a point before deviating to a non-linear step at the end.
I am using extent to set the bounds of the axes and as I understand it imshow will plot the data with a regular and linear step between the start and end points. I would like to fix the new (blue) Y-axis reference to the data to be plotted so that the data is presented at the correct position with respect to the Y-Axis value.
As an example I have the following code:
testData = np.array([[1,1,1,1], [2,2,2,2], [3,3,3,3], [4,4,4,4]])
x_axisTest = [1,2,3,4]
y_axisTest = [2,4,8,12]
fig, (ax1) = plt.subplots()
pcm = ax1.imshow(testData, interpolation='nearest', cmap=cm.jet, origin='upper',
aspect='auto', # vmin = 20, vmax = 60,
extent =[x_axisTest[0], x_axisTest[3], y_axisTest[3],
y_axisTest[0]])
As seen the data is linearly plotted even though the Y-axis step changes from 2 (2,4...) to 4 (...8, 12). What I would like is the data to be interpreted or stretched/compressed between Y-axis values 4 to 12 based on the new step value.
I've been looking into resampling the data which is maybe the preferred option but again I'm not sure how best to apply this and ensure I keep the Y-axis matched with the data. My concern is that I may also shift the linear portion of the data. I would appreciate a nudge in the right direction.
Thank you in advance for your assistance.
I am trying to plot some precipitation data. The code I'm using is modified slightly from this code here.
The code works fine when I plot using the data from the site used in the link, but when I use a different dataset I have, it doesn't plot. The biggest difference between this dataset and the dataset used in the link's example, is my dataset is global data. The dataset I am using is also netcdf, is not masked, and I am loading it the same way as the example.
I am familiar with the data and know for a fact I should be seeing something and the contour values used in the example are reasonable for this other set of data I am using.
My code is the same, expect for some changes in the section that plots the figure (below) which I have modified so it will plot a specific area instead of CONUS like in the example (using ax.set_extent).
When I do not set the extent it appears to plot the data, but then none of the boundaries (coastlines, state lines, etc.) do not plot. Based on this, I'm guessing it's something with either the dataset itself, something with set_extent, or a combination of things that is causing it to go wrong. I am not getting back any kind of errors when I plot it, either way. However, there might be something else I'm missing with it.
In the end, I'm actually comparing my dataset to the dataset used in the example link, so I would like them in the same projection.
Thanks for any insight and let me know if you need more information about the data itself!
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(1, 1, 1, projection=proj)
ax.set_extent((x1,x0,y0,y1))
# draw coastlines, state and country boundaries, edge of map.
ax.coastlines()
ax.add_feature(cfeature.BORDERS)
ax.add_feature(cfeature.STATES)
cs1 = ax.contourf(ym, xm, data1, clevs, cmap=cmap, norm=norm)
# add colorbar.
cbar = plt.colorbar(cs1, orientation='horizontal')
#cbar.set_label(data1.units)
#ax.set_title(prcpvar.long_name + ' for period ending ' + nc.creation_time)
plt.show()
plt.savefig('ncep_model')
Results when extent is not included in code above:
Edit 1:
I'll add that I was able to successfully plot the data with this code below (from a default template I made). I tried to change the projection to stereographic, but I was having trouble getting it to plot correctly using basemap because I've never used it before. As an alternative, if you can't figure out the error with the code above and could instead help with changing the projection for the code below, I would also take that. At this point I just want my data to plot correctly in the correct projection I want!
(I also included the results for the code below to confirm that the data should be showing up in this location)
LLlat = 40.
LLlon = 263.
URlat = 44.
URlon = 270.
lat = xm
lon = ym
%matplotlib inline
plt.figure(1,figsize=(10, 8),)
plt.title('Convective Precipitation 8/28/2018 0Z (in) Valid July 2018')
map = Basemap(projection='cyl',\
llcrnrlat=LLlat,urcrnrlat=URlat,\
llcrnrlon=LLlon,urcrnrlon=URlon,\
rsphere=6371200.,resolution='i')
map.drawcoastlines(linewidth=0.5) # Draw some coastlines
map.drawstates(linewidth=0.5) # Draw some coastlines
map.drawrivers(color='#000000')
map.drawparallels(np.arange(-90.,91.,30),labels=[1,0,0,0]) # Drawing lines of latitude
map.drawmeridians(np.arange(0.,330.,60),labels=[0,0,0,1]) # Drawing lines of longitude
lons,lats = map(lon,lat) # Setting up the grid in cylindrical coords.
cs = plt.contourf(lons,lats,data1[:,:], clevs,cmap=cmap, norm=norm)
cb = plt.colorbar(cs,orientation='horizontal')
plt.show()
Edit 2:
I've added the resulting plot when I don't include the set_extent in the first chunk of code (Don't know if that will help at all, but thought I'd include it as well)
So it'd be really useful to have more information on your data, like a link to sample file, but my guess is that your data do not give coordinates in a stereographic projection, unlike the original data. When plotting with Cartopy, if you do not specify otherwise, all plot commands assume that the x,y values given are in the projection specified for the axes (for the original code this was ccrs.Stereographic). If this is not the case, such as when plotting lon/lats, you need to specify this by passing transform to the plotting command, as below where I specify that the x,y values are lat/lons:
data_proj = ccrs.PlateCarree()
cs1 = ax.contourf(ym, xm, data1, clevs, cmap=cmap, norm=norm,
transform=data_proj)
I have 2 sets of coordinates that I want to plot on the same matrix.
This is my code:
self.ax.imshow(arr,cmap=plt.cm.Greys_r, interpolation='none')
self.ax.imshow(arr.T, cmap=plt.cm.Greys_r, interpolation = 'none')
However this does not work. It only seems to plot the one that is called last.
What am I doing wrong?
I'm not sure I entirely understand the question, but if you just want the sum of both matrices plotted, then try,
self.ax.imshow(arr+are.T,cmap=plt.cm.Greys_r, interpolation='none')
though note it only works if arr and are.T have equal shape.
I'm trying to fill the area under a curve with matplotlib. The script below works fine.
import matplotlib.pyplot as plt
from math import sqrt
x = range(100)
y = [sqrt(i) for i in x]
plt.plot(x,y,color='k',lw=2)
plt.fill_between(x,y,0,color='0.8')
plt.show()
However if I set the y-scale to logarithmic (see below). It sometimes fills the area above the curve ! Can anyone help me? I would like to fill the area between the curve and y = 0.
x = range(100)
y = [sqrt(i) for i in x]
plt.plot(x,y,color='k',lw=2)
plt.fill_between(x,y,0,color='0.8')
plt.yscale('log')
plt.show()
Thanks in advance!
With a logarithmic y-scale, fill_between(x, y, 0) tells matplotlib to fill the region between log(0) = -infinity and log(y). Naturally, it balks. You can avoid the problem by changing 0 to some small number like 1e-6.
As mentioned, 0 -> -inf in a log scale. Thus, any plotted value that was less than or equal to zero would be problematic (requiring an infinite ylim in log space). This problem exists independently of whether you are using fill_between() or not.
Fortunately, matplotlib provides a way to handle this nicely. In the default behavior, matplotlib masks the values of every value less than or equal to zero. In your example, this means that your entire y=0 line is masked and excluded from the polygon defining the filled-between area. The result is that the polygon is simply closed by drawing a line from (100,10) down and leftward to (0,0). Another option is to clip the values. In this case, they are set to 1e-300 and are not consulted when determining the ylim of the plot. So to get your desired result, do the following:
plt.yscale('log', nonposy='clip')