How Does One Turn Contour Lines into Filled Contours

How does one turn contour lines into filled contours?

A solution that uses the raster package (which calls rgeos and sp). The output is a SpatialPolygonsDataFrame that will cover every value in your grid:

library('raster')
rr <- raster(t(volcano))
rc <- cut(rr, breaks= 10)
pols <- rasterToPolygons(rc, dissolve=T)
spplot(pols)

Here's a discussion that will show you how to simplify ('prettify') the resulting polygons.

Sample Image

Is there a function in python to fill the area between two contourlines each given by different functions?

The following code first creates some test data. The blue lines indicate where zzmax and zzmin are equal to 1. The subplot at the right shows in red the region where both zzmax is smaller than 1 and zzmin is larger than 1.

from matplotlib import pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
from scipy.ndimage import gaussian_filter

xx = np.linspace(0, 10, 100)
yy = np.linspace(0, 8, 80)

np.random.seed(11235813)
zzmax = gaussian_filter(np.random.randn(len(yy), len(xx)) * 10 + 1, 8)
zzmin = gaussian_filter(np.random.randn(len(yy), len(xx)) * 10 + 0.9, 8)

fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(15, 4))
cnt1 = ax1.contourf(xx, yy, zzmax, cmap='RdYlGn')
plt.colorbar(cnt1, ax=ax1)
ax1.contour(xx, yy, zzmax, levels=[1], colors='skyblue', linewidths=3)
ax1.set_title('zzmax')

cnt2 = ax2.contourf(xx, yy, zzmin, cmap='RdYlGn')
plt.colorbar(cnt2, ax=ax2)
ax2.contour(xx, yy, zzmin, levels=[1], colors='skyblue', linewidths=3)
ax2.set_title('zzmin')

ax3.contourf(xx, yy, (zzmax <= 1) & (zzmin >= 1), levels=[0.5, 2], cmap=ListedColormap(['red']), alpha=0.3)
ax3.set_title('zzmax ≤ 1 and zmin ≥ 1')

plt.tight_layout()
plt.show()

coloring between contours

In R, how does one place multiple filled.contour() plots in a single device?

I would use levelplot from package lattice. You can get multiple panels, and the plots really look nice.

Look at figure 6.9 in chapter 6 of the Lattice book:

http://lmdvr.r-forge.r-project.org/figures/figures.html

That way you are not stuck with hacking the filled contour code. ( I did try searching for something in the rhelp and SO archives and came up empty.)

How to fill closed contour region with white

Here's an approach:

  • Convert image to grayscale
  • Find contours and fill in the contour
  • Perform morphological transformations to remove unwanted sections

We find contours then fill in the contour with cv2.drawContours() using -1 for the thickness parameter

To remove the line section, we can use morphological transformations

import cv2

image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

cnts = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
cv2.drawContours(gray,[c], 0, (255,255,255), -1)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20,20))
opening = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel, iterations=2)

cv2.imshow('gray', gray)
cv2.imshow('opening', opening)
cv2.imwrite('opening.png', opening)
cv2.waitKey(0)

Overlaying contour lines on top of contourf plot

To fix this you have to use caxis to set the limits for the contourf plot:

clc; clear all; close all;

x = linspace(-2*pi,2*pi);
y = linspace(0,4*pi);
[X1,Y1] = meshgrid(x,y);
Z1 = sin(X1)+cos(Y1);

[X2,Y2] = meshgrid(x,y);
Z2 = 1000*(sin(1.2*X2)+2*cos(Y2));

figure;
contourf(X1,Y1,Z1);
shading flat;
caxis([min(min(Z1)) max(max(Z1))]);
hold on;
contour(X2,Y2,Z2,'k');

You can replace min(min(Z1)) and max(max(Z1)) with the upper and lower limits that you want. This results in this plot:

Sample Image

Hide contour linestroke on pyplot.contourf to get only fills

I finally found a proper solution to this long-standing problem (currently in Matplotlib 3), which does not require multiple calls to contour or rasterizing the figure.

Note that the problem illustrated in the question appears only in saved publication-quality figures formats like PDF, not in lower-quality raster files like PNG.

My solution was inspired by this answer, related to a similar problem with the colorbar. A similar solution turns out to solve the contour plot as well, as follows:

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(123)
x, y = np.random.uniform(size=(100, 2)).T
z = np.exp(-x**2 - y**2)
levels = np.linspace(0, 1, 100)

cnt = plt.tricontourf(x, y, z, levels=levels, cmap="ocean")

# This is the fix for the white lines between contour levels
for c in cnt.collections:
c.set_edgecolor("face")

plt.savefig("test.pdf")

Here below is an example of contours before the fix

Sample Image

And here below is the same figure after the above fix

Sample Image

How to get contour lines around the grids in R-raster?

I'd use a combination of clump() and rasterToPolygons():

library(raster)
library(rgeos) ## For dissolve = TRUE in rasterToPolygons()

## Recreate your data
set.seed(2)
r <- raster(nrow = 10, ncol = 10)
r[] <- runif(ncell(r))
plot(r)

## Compute and then plot polygons surrounding cells with values greater than 0.6
SP <- rasterToPolygons(clump(r > 0.6), dissolve = TRUE)
plot(SP, add = TRUE)

Sample Image



Related Topics



Leave a reply



Submit