Skip to content

Commit 0274666

Browse files
committed
Completely reworked to make use of matplotlib.
1 parent 76e2622 commit 0274666

File tree

8 files changed

+63
-75
lines changed

8 files changed

+63
-75
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pypng==0.0.18
55
PyPlatec==1.4.0
66
protobuf==3.0.0a3
77
six==1.10.0
8+
matplotlib

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
'console_scripts': ['worldengine=worldengine.cli.main:main'],
2727
},
2828
'install_requires': ['PyPlatec==1.4.0', 'pypng>=0.0.18', 'numpy>=1.9.2, <= 1.10.0.post2',
29-
'argparse==1.2.1', 'noise==1.2.2', 'protobuf==3.0.0a3'],
29+
'argparse==1.2.1', 'noise==1.2.2', 'protobuf==3.0.0a3',
30+
'matplotlib'],
3031
'license': 'MIT License'
3132
}
3233

tests/blessed_images/generated_blessed_images.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import os
1111
from worldengine.world import *
1212
from worldengine.draw import *
13+
from worldengine.draw_plots import *
1314
from worldengine.image_io import PNGWriter
1415

1516

tests/draw_test.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import numpy
44
from worldengine.draw import _biome_colors, draw_simple_elevation, elevation_color, \
55
draw_elevation, draw_riversmap, draw_grayscale_heightmap, draw_ocean, draw_precipitation, \
6-
draw_world, draw_temperature_levels, draw_biome, draw_scatter_plot, draw_hypsographic_plot, \
7-
draw_satellite
6+
draw_world, draw_temperature_levels, draw_biome, draw_scatter_plot, draw_satellite
7+
from worldengine.draw_plots import draw_hypsographic_plot
88
from worldengine.biome import Biome
99
from worldengine.world import World
1010
from worldengine.image_io import PNGWriter, PNGReader
@@ -156,12 +156,9 @@ def test_draw_scatter_plot(self):
156156
self._assert_img_equal("scatter_28070", target)
157157

158158
def test_draw_hypsographic_plot(self):
159-
x_bins = 800
160-
y_bins = 600
161159
w = World.open_protobuf("%s/seed_28070.world" % self.tests_data_dir)
162-
target = PNGWriter.grayscale_from_dimensions(x_bins, y_bins, channel_bitdepth=8)
163-
draw_hypsographic_plot(w, target, x_bins, y_bins)
164-
self._assert_img_equal("hypsographic_28070", target)
160+
plot = draw_hypsographic_plot(w)
161+
# self._assert_img_equal("hypsographic_28070", target) # TODO: find way to compare these
165162

166163
def test_draw_satellite(self):
167164
w = World.open_protobuf("%s/seed_28070.world" % self.tests_data_dir)

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ deps =
1111
six
1212
pypng
1313
h5py
14+
matplotlib
1415

1516
[testenv]
1617
deps =

worldengine/cli/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
from worldengine.draw import draw_ancientmap_on_file, draw_biome_on_file, draw_ocean_on_file, \
88
draw_precipitation_on_file, draw_grayscale_heightmap_on_file, draw_simple_elevation_on_file, \
99
draw_temperature_levels_on_file, draw_riversmap_on_file, draw_scatter_plot_on_file, \
10-
draw_hypsographic_plot_on_file, draw_satellite_on_file, draw_icecaps_on_file
10+
draw_satellite_on_file, draw_icecaps_on_file
11+
from worldengine.draw_plots import draw_hypsographic_plot_on_file
1112
from worldengine.plates import world_gen, generate_plates_simulation
1213
from worldengine.imex import export
1314
from worldengine.step import Step

worldengine/draw.py

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -734,64 +734,6 @@ def draw_scatter_plot(world, size, target):
734734
target.set_pixel(int(nx), (size - 1) - int(ny), (r, 128, b, 255))
735735

736736

737-
def draw_hypsographic_plot(world, target, x_bins, y_bins):
738-
# Will draw a Hypsograhpic plot that contains information about the distribution of elevations in the world.
739-
# y-axis shows the elevation, x-axis shows how often a certain elevation occurs.
740-
# For further details see:
741-
# https://en.wikipedia.org/wiki/Elevation#Hypsography
742-
# http://www.ngdc.noaa.gov/mgg/global/etopo1_surface_histogram.html
743-
744-
assert int(x_bins) > 0 and int(y_bins) > 0, "Hypsographic curve needs more than 0 bins."
745-
746-
# set colors
747-
color_none = target.get_max_colors() # white
748-
color_full = int(color_none / 2) # gray
749-
color_line = 0 # black
750-
color_percent_sep = int(color_none * 0.8) # light-gray
751-
752-
# Prepare a list of available elevations. Scale them to the y-axis and put them into a sorted list,
753-
# smallest point to highest.
754-
e = world.elevation['data']
755-
e_min = e.min()
756-
e_max = e.max()
757-
e = (e - e_min) / (e_max - e_min) # normalize to [0, 1]
758-
e *= int(y_bins) - 0.01 # instead of "- 1", small trick to make the last bin contain more than one point
759-
e = numpy.sort(e, axis=None) # flatten the array and order values by height
760-
e = e.astype(dtype=numpy.uint16) # do not round (the graph wouldn't change, just shift)
761-
762-
# Fill the plot.
763-
# Start by calculating how many points of the heightmap have to be represented by a single bin (n).
764-
# Then step through the bins and fill in points from highest to lowest. Every bin is set to the average height of
765-
# the n points it represents.
766-
# Instead of drawing to [y, x] draw to [y_bins - y - 1, x_bins - x - 1] to flip the output in x- and y-direction.
767-
n = e.size / float(x_bins)
768-
for x in range(x_bins):
769-
avg = sum(e[int(x * n):int((x + 1) * n)])
770-
avg = int(avg / float(n)) # average height of n height-points
771-
for y in range(y_bins):
772-
target[y_bins - y - 1, x_bins - x - 1] = color_none if y > avg else color_full
773-
774-
# Draw a vertical line every ten percent.
775-
step = x_bins / 10.0
776-
for i in range(1, 10): # no lines at 0 and (x_bins - 1)
777-
x = int(step * i)
778-
for y in range(y_bins):
779-
target[y, x_bins - x - 1] = color_percent_sep
780-
781-
# Map sea-level etc. to appropriate y-positions in the graph.
782-
lines = []
783-
for threshold in world.elevation['thresholds']: # see generation.py->initialize_ocean_and_thresholds() for details
784-
if threshold[1] is None:
785-
continue # TODO: remove if the thresholds are ever guaranteed to be numbers
786-
lines.append(int(numpy.interp(threshold[1], [e_min, e_max], [0, y_bins])))
787-
788-
# Draw lines for sea-level, hill-level etc. The lines will get lighter with increasing height.
789-
for i in range(len(lines)):
790-
color = numpy.interp(i, [0, len(lines)], [color_line, color_none])
791-
for x in range(x_bins):
792-
target[y_bins - lines[i] - 1, x] = color
793-
794-
795737
# -------------
796738
# Draw on files
797739
# -------------
@@ -869,14 +811,6 @@ def draw_scatter_plot_on_file(world, filename):
869811
img.complete()
870812

871813

872-
def draw_hypsographic_plot_on_file(world, filename):
873-
x_bins = 800
874-
y_bins = 600
875-
img = PNGWriter.grayscale_from_dimensions(x_bins, y_bins, filename, channel_bitdepth=8)
876-
draw_hypsographic_plot(world, img, x_bins, y_bins)
877-
img.complete()
878-
879-
880814
def draw_satellite_on_file(world, filename):
881815
img = PNGWriter.rgba_from_dimensions(world.width, world.height, filename)
882816
draw_satellite(world, img)

worldengine/draw_plots.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import numpy
2+
import matplotlib.pyplot as plot
3+
4+
5+
def draw_hypsographic_plot(world):
6+
# Will draw a Hypsograhpic plot that contains information about the distribution of elevations in the world.
7+
# y-axis shows the elevation, x-axis shows how often a certain elevation occurs.
8+
# For further details see:
9+
# https://en.wikipedia.org/wiki/Elevation#Hypsography
10+
# http://www.ngdc.noaa.gov/mgg/global/etopo1_surface_histogram.html
11+
12+
# Set up variables.
13+
sea_level = world.sea_level()
14+
fig = plot.figure()
15+
p = fig.add_subplot(111)
16+
17+
# Prepare a list of available elevations by putting them into a sorted list, smallest point to highest.
18+
# 0 will refer to sea-level.
19+
y = world.elevation['data'] - sea_level
20+
y = numpy.sort(y, axis=None) # flatten the array and order values by height
21+
22+
# Corresponding x-values. Inverted so the highest values are left instead of right. x refers to %, hence [0, 100].
23+
x = numpy.arange(100, 0, -100.0 / y.size)
24+
25+
# Plot the data.
26+
p.plot(x, y)
27+
28+
# Cosmetics.
29+
p.set_ylim(y.min(), y.max())
30+
p.fill_between(x, y.min(), y, color='0.8')
31+
p.set_xlabel("Cumulative Area (% of World's Surface)")
32+
p.set_ylabel("Elevation (no units)")
33+
p.set_title("Hypsographic Curve - %s" % world.name)
34+
35+
# Draw lines for sea-level, hill-level etc. The lines will get lighter with increasing height.
36+
th = world.elevation['thresholds'] # see generation.py->initialize_ocean_and_thresholds() for details
37+
for i in range(len(th)):
38+
if th[i][1] is None:
39+
continue
40+
color = numpy.interp(i, [0, len(th)], [0, 1.0]) # grayscale values, black to white; white will never be used
41+
p.axhline(th[i][1] - sea_level, color=str(color), linewidth=0.5)
42+
p.text(99, th[i][1] - sea_level, th[i][0], fontsize=8, horizontalalignment='right', verticalalignment='bottom' if th[i][1] - sea_level > 0 else 'top')
43+
44+
p.set_xticks(range(0, 101, 10))
45+
46+
return fig
47+
48+
49+
def draw_hypsographic_plot_on_file(world, filename):
50+
fig = draw_hypsographic_plot(world)
51+
fig.savefig(filename)
52+
plot.close(fig)

0 commit comments

Comments
 (0)