Matplotlib imshow checkerboard plot with changing data ranges - python

I have a dataset which has a different range of the x coordinate at each y coordinate, without a specific rule or a fixed delta_x. E.g.
y=0 -> x is 40 values in range(20, 55)
y=1 -> x is 40 values in range(24, 49)
y=2 -> x is 40 values in range(23, 59)
...
Is there a way to get a checkerboard plot with such data using imshow?
I have tried changing the extent at each y value in a loop, but this just shifts each row to the last extent i set. In the plots below, the horizontal extent at the top should be [1410, 2190], and the horizontal extent at the bottom is [1453, 4970]. The red and white lines are a simple plot on top, and should follow the area shaded in red and yellow. See image here
I have tried using tricontourf (after Oliver W.'s suggestion here), which handles the dataset fine, the plot is accurate. You can also see how the horizontal extent changes. There are some artifacts in the image however. I'd like to use rectangles without interpolation, instead of interpolated triangles, if possible. See image here
I have tried appending the minimum and maximum values of all x at each y, and using those values for the horizontal extent, and it kinda works. See image here
It's still not accurate, and I'm not sure why. I can get a slightly better/more correct image by changing the values manually, first try. See image here
I'd be grateful for any comments or suggestions.

Related

Python matplotlib plot background

I want to compare a plot from a paper to my simulation results.
Therefore it would be convenient to plot my results with the ref pic in the background.
the x value range i choose to be the same as the ref pic
y should also be close to the ref pic.
Or i can set the y range also to the same values as the ref pic.
i tryed
x=range(len(P))
plt.plot(x,P)
img=plt.imread("REF.jpg")
plt.imshow(img)
plt.show()
But it chooses the scale i think according to pixels?
and my other plot was a miniature on it.
if i use extend and one dimension is much larger then the other, one can see nothing on the pic because of the bad aspect ratio

Matplotlib imshow - fixed colour of pixels outside selected clim range

I am using imshow() to create pseudo-coloured maps of matrices of values (2d numpy arrays). Using clim argument one can set the range of values (below 1 and 6) to be represented within the colour scale (see below). This way for example all outliers (whether 7 or 7000000) will be yellow. This skews the perception of the image, as the reader doesn't know if this pixel is 6 or 700000.
Does anyone know of any way to colour all values outside of this range some other fixed colour of choice, for example, magenta?

An alternative to using standard marker for 2D color plot?

At the moment I have a somewhat crude python program that I would like to modify to do the following:
Read in three columns of data from a single file (X,Y,C) which are then plotted as a 2D X,Y scatter plot with the C value representing the color map value. Each X,Y point represents the center of a square box of fixed size which will be colored based on the C value. The X,Y coordinates are such that there won't be any overlapping boxes - although there will be gaps where there are no coordinates. The size of the box will be fixed for each input file (but can vary from one file to the next) and the program is supposed to color in each square box depending on the C value. For instance, the desired plot for one particular input file might have 5,000 X,Y coordinates somewhere in the range X from 1000 to 6000 and Y from 2000 to 7000, with the desired box size being 40, and the color range going from 1 to 1700.
Currently the program is a hack based on using the standard marker to colour each box, so essentially the marker represents the size of the box. It works ok but requires selecting the correct marker size and also adjusting the size of the plot to ensure that boxes (i.e. the markers) fit without gap or overlap. This adjustment is specific to each input file - i.e. the X,Y range and the box size (based on minimum distance between points). So I am thinking how to automate this so that the program can read in any file (regardless of box size) and color in each box without requiring a lot of user input (perhaps box size will need to be entered somewhere) - so I guess not using the standard marker.
Current code:
plt.figure(figsize=(10.0, 10.5))
plt.rcParams['axes.facecolor'] = '#55AAFF' # background color
plt.scatter(X, Y, c=colrsabove, s=marker_size, marker='s', alpha=0.8, cmap='YlOrRd')

Extracting actual values from RGB-bands

I have a (geographic) raster-image in RGB. I also have an external legend displaying the heights according to a certain color. In below figure, I have sampled this legend, hopefully revealing its RGB-characteristics. I have plotted these values to their actual height values on the X-axis.
Now, is it possible to directly derive height from the pixel's RGB-value? Ultimately, I'm looking for a simple formula which is able to translate my RGB values into one height value (e.g. H = aR + bG + c*B) Any hint or tips? Is it even possible at all?

Understanding quiver plot scale

I am trying to understand, how scale works in quiver plot. I have found an explanation here , but I want to double check, that I understand what the author says.
When he says
Setting the angles keyword to 'xy' means that the vector components are scaled according to the physical axis units rather than geometrical units on the page.
Does he mean that, let's say, if I have some movement which is 1 pixel (to make it simple, let's say per 1 second) and this happens on a 232x232 image (actual thing I have), will the 1px/s movement show up scaled 232 times ? That is 1/232 ? Or will the 1px/s appear as representing 1 px (no matter the angle to the axis), that is it will take 1px, however that pixel appears on the image with 232 x 232 pixel size image ?
The actual scaling factor which multiplicatively converts vector component units to physical axis units is width/scale where width is the width of the plot in physical units and scale is the number specified by the scale keyword argument of quiver.
Does that mean that if say, I choose my scale to be 10, a vector that is actually 10px/s will appear as 1px/s ? (I know these are very basic questions but I am confused with the "physical axis" and the "geometrical units on the page").
I think I will test this by simply having two images, one sized, say 40x40 and the other 160x160, with same 1px movement and see how that affects the plot.
What I would like to do is to actually have 1px/s representing a 1px length, whatever that length is as represented by the plot (using matplotlib.pyplot).
OK, so I played around with synthetic data and using either " angles = 'xy' " or just leaving it out (i.e. having something like
q = pl.quiver(a[valid,0],a[valid,1],a[valid,2],a[valid,3], color='r',**kw),
where one of the kwargs is your scale factor.
It seems to scale with the width of the plot. I used
pl.draw()
pl.xticks(np.arange(0,120,32))
pl.yticks(np.arange(0,100,32))
pl.grid(color = 'y')
pl.savefig(new_file, bbox = "tight")
to save my figure (the actual images were 120x100 (in this case) , 120x120 and 64x64.
What I did to test it:
I created one pixel shifts in the horizontal and vertical, then on some other images, a diagonal shift of 5px (3 right and 4 down).
To get 1px/s vector to take the length of 1px as in your image, you have to set the scale to the width of your plot i.e. in my case it was either 64 or 120. I wanted to see if having a non-square image will affect the scale, so I cropped the image to 100px height. From the few tests I have done, it does not seem to have any effect. It would be worth testing with different pixel shifts, but since the horizontal/vertical shifts were not scaled differently using different side length image, I think it is safe to assume it behaves as expected.
I wonder what is the reason for such scaling of vectors...

Categories

Resources