Display objects#
A striplog
depends on a hierarchy of objects. This notebook shows the objects related to display:
Decor: One element from a legend — describes how to display a Rock.
Legend: A set of Decors — describes how to display a set of Rocks or a Striplog.
Decor#
from striplog import Decor
A Decor attaches a display style to a Rock. From the docs:
A single display style. A Decor describes how to display a given set of Component properties.
In general, you will not usually use a Decor on its own. Instead, you will want to use a Legend, which is just a list of Decors, and leave the Decors to the Legend.
We are going to need a Component
to make a Decor
. ‘Components’ represent things like rock types.
from striplog import Component
r = {'colour': 'grey',
'grainsize': 'vf-f',
'lithology': 'sand',
'porosity': 0.123
}
rock = Component(r)
rock
colour | grey |
grainsize | vf-f |
lithology | sand |
porosity | 0.123 |
d = {'color': '#267022',
'component': rock,
'width': 3
}
decor = Decor(d)
decor
colour | #267022 | ||||||||
component |
| ||||||||
width | 3.0 | ||||||||
hatch | None |
from striplog import Component
r = {'colour': 'grey',
'grainsize': 'vf-f',
'lithology': 'sand',
'porosity': 0.123
}
rock = Component(r)
rock
colour | grey |
grainsize | vf-f |
lithology | sand |
porosity | 0.123 |
Like Rock
s, we instantiate Decor
s with a dict
of properties:
d = {'color': '#267022',
'component': rock,
'width': 3
}
decor = Decor(d)
decor
colour | #267022 | ||||||||
component |
| ||||||||
width | 3.0 | ||||||||
hatch | None |
Or instantiate with keyword parameters:
Decor(colour='#86f0b6',
component=Component({'colour': 'grey', 'grainsize': 'vf-f', 'porosity': 0.123, 'lithology': 'sand'}),
width=3.0
)
colour | #86f0b6 | ||||||||
component |
| ||||||||
width | 3.0 | ||||||||
hatch | None |
You can access its attributes. It has two ways to understand colour:
print("Hex: {}... and RGB: {}".format(decor.colour, decor.rgb))
Hex: #267022... and RGB: (38, 112, 34)
print(decor)
Decor({'_colour': '#267022', 'component': Component({'colour': 'grey', 'grainsize': 'vf-f', 'lithology': 'sand', 'porosity': 0.123}), 'width': 3.0, 'hatch': None})
%matplotlib inline
decor.plot()
decor.hatch = '+'
decor.plot()
There are the standard matplotlib
hatch patterns:
hatches = "\/|+x-.o*"
for h in hatches:
Decor({'component': Component({'hatch':h}), 'hatch': h, 'colour': '#eeeeee'}).plot()
And there are some custom ones. These really need to be reconciled and implemented in a more flexible way, perhaps even going as far as a redesign of the mpl implementation.
hatches = "pctLbs!=v^"
for h in hatches:
Decor({'component': Component({'hatch':h}), 'hatch': h, 'colour': '#eeeeee'}).plot(fmt="{hatch}")
We can disaply hatches in a single plot for quick reference:
import matplotlib.pyplot as plt
hatches = ['.', '..', 'o', 'p', 'c', '*', '-', '--', '=', '==', '|',
'||', '!', '!!', '+', '++', '/', '\\', '//', '\\\\', '///',
'\\\\\\', 'x', 'xx', '^', 'v', 't', 'l', 'b', 's']
fig, axs = plt.subplots(figsize=(16,5.25), ncols=10, nrows=3)
fig.subplots_adjust(hspace=0.5)
for ax, h in zip(axs.flatten(), hatches):
ax.set_title(h)
Decor(colour='#eeeeee',
component=Component({'hatch': h}),
hatch=h).plot(fmt='', ax=ax)
Legend#
A look-up table to assist in the conversion of Components to a plot colour.
We’ll define a legend in a CSV file. I can’t think of a better way for now. It would be easy to make a web form to facilitate this with, for example, a colour picker. It may not be worth it, though; I imagine one would create one and then leave it alone most of the time.
l = u"""colour, width, component lithology, component colour, component grainsize
#F7E9A6, 3, Sandstone, Grey, VF-F
#FF99CC, 2, Anhydrite, ,
#DBD6BC, 3, Heterolithic, Grey,
#FF4C4A, 2, Volcanic, ,
#86F0B6, 5, Conglomerate, ,
#FF96F6, 2, Halite, ,
#F2FF42, 4, Sandstone, Grey, F-M
#DBC9BC, 3, Heterolithic, Red,
#A68374, 2, Siltstone, Grey,
#A657FA, 3, Dolomite, ,
#FFD073, 4, Sandstone, Red, C-M
#A6D1FF, 3, Limestone, ,
#FFDBBA, 3, Sandstone, Red, VF-F
#FFE040, 4, Sandstone, Grey, C-M
#A1655A, 2, Siltstone, Red,
#363434, 1, Coal, ,
#664A4A, 1, Mudstone, Red,
#666666, 1, Mudstone, Grey, """
from striplog import Legend
legend = Legend.from_csv(text=l)
legend[:5]
hatch | component | colour | width | ||||||
---|---|---|---|---|---|---|---|---|---|
None |
| #f7e9a6 | 3.0 | ||||||
None |
| #ff99cc | 2.0 | ||||||
None |
| #dbd6bc | 3.0 | ||||||
None |
| #ff4c4a | 2.0 | ||||||
None |
| #86f0b6 | 5.0 |
Duplicate lithologies will result in a warning. To avoid strange results, you should fix the problem by removing duplicates.
l = u"""colour, component lithology
#F7E9A6, Sandstone
#F2FF42, Sandstone
#FF99CC, Anhydrite
#DBD6BC, Heterolithic
#FF4C4A, Volcanic
#86F0B6, Conglomerate
#FFD073, Sandstone
"""
Legend.from_csv(text=l)
/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/striplog/legend.py:687: UserWarning: This legend contains duplicate components.
warnings.warn(w)
/opt/hostedtoolcache/Python/3.10.4/x64/lib/python3.10/site-packages/striplog/legend.py:687: UserWarning: This legend contains duplicate components.
warnings.warn(w)
hatch | component | colour | width | ||
---|---|---|---|---|---|
None |
| #f7e9a6 | None | ||
None |
| #f2ff42 | None | ||
None |
| #ff99cc | None | ||
None |
| #dbd6bc | None | ||
None |
| #ff4c4a | None | ||
None |
| #86f0b6 | None | ||
None |
| #ffd073 | None |
We can also export a legend as CSV text:
print(legend.to_csv())
colour,hatch,width,component grainsize,component colour,component lithology
#f7e9a6,None,3.0,vf-f,grey,sandstone,
#ff99cc,None,2.0,,,anhydrite,
#dbd6bc,None,3.0,,grey,heterolithic,
#ff4c4a,None,2.0,,,volcanic,
#86f0b6,None,5.0,,,conglomerate,
#ff96f6,None,2.0,,,halite,
#f2ff42,None,4.0,f-m,grey,sandstone,
#dbc9bc,None,3.0,,red,heterolithic,
#a68374,None,2.0,,grey,siltstone,
#a657fa,None,3.0,,,dolomite,
#ffd073,None,4.0,c-m,red,sandstone,
#a6d1ff,None,3.0,,,limestone,
#ffdbba,None,3.0,vf-f,red,sandstone,
#ffe040,None,4.0,c-m,grey,sandstone,
#a1655a,None,2.0,,red,siltstone,
#363434,None,1.0,,,coal,
#664a4a,None,1.0,,red,mudstone,
#666666,None,1.0,,grey,mudstone,
Builtin legends#
There are several:
'nsdoe': Nova Scotia Dept. of Energy
'nagmdm__6_2': USGS N. Am. Geol. Map Data Model 6.2 <<< default
'nagmdm__6_1': USGS N. Am. Geol. Map Data Model 6.1
'nagmdm__4_3': USGS N. Am. Geol. Map Data Model 4.3
'sgmc': USGS State Geologic Map Compilation
legend = Legend.builtin('nsdoe')
legend
hatch | component | colour | width | ||||||
---|---|---|---|---|---|---|---|---|---|
None |
| #f7e9a6 | 3.0 | ||||||
None |
| #ff99cc | 2.0 | ||||||
None |
| #dbd6bc | 3.0 | ||||||
None |
| #ff4c4a | 2.0 | ||||||
None |
| #86f0b6 | 5.0 | ||||||
None |
| #ff96f6 | 2.0 | ||||||
None |
| #f2ff42 | 4.0 | ||||||
None |
| #dbc9bc | 3.0 | ||||||
None |
| #a68374 | 2.0 | ||||||
None |
| #a657fa | 3.0 | ||||||
None |
| #ffd073 | 4.0 | ||||||
None |
| #a6d1ff | 3.0 | ||||||
None |
| #ffdbba | 3.0 | ||||||
None |
| #ffe040 | 4.0 | ||||||
None |
| #a1655a | 2.0 | ||||||
None |
| #363434 | 1.0 | ||||||
None |
| #664a4a | 1.0 | ||||||
None |
| #666666 | 1.0 |
There is also a default legend, which you can call with Legend.default()
(no arguments).
Legend.default()
hatch | component | colour | width | ||
---|---|---|---|---|---|
None |
| #fdf43f | None | ||
None |
| #ffff89 | None | ||
None |
| #ffffd5 | None | ||
None |
| #fffae9 | None | ||
None |
| #fffac8 | None | ||
None |
| #ffffb7 | None | ||
None |
| #faee7a | None | ||
None |
| #f4efe4 | None | ||
None |
| #f1e5df | None | ||
None |
| #e4d0be | None | ||
None |
| #e4d8be | None | ||
None |
| #fff6d9 | None | ||
None |
| #e0c59e | None | ||
None |
| #e0d2b4 | None | ||
None |
| #dbcca9 | None | ||
None |
| #f5e1bd | None | ||
None |
| #e0b09e | None | ||
None |
| #cfbb8f | None | ||
None |
| #e1e3c3 | None | ||
None |
| #e5dbb3 | None | ||
None |
| #dcd5b4 | None | ||
None |
| #d3ca9f | None | ||
None |
| #c9be89 | None | ||
None |
| #bcaf6c | None | ||
None |
| #bfa743 | None | ||
None |
| #d2c27c | None | ||
None |
| #ffeebf | None | ||
None |
| #ffe59d | None | ||
None |
| #ffdf85 | None | ||
None |
| #fee670 | None | ||
None |
| #fee258 | None | ||
None |
| #fedb2e | None | ||
None |
| #f7f3a1 | None | ||
None |
| #ffcf81 | None | ||
None |
| #ffcc99 | None | ||
None |
| #ffe389 | None | ||
None |
| #ffdb67 | None | ||
None |
| #ffd345 | None | ||
None |
| #ffcb23 | None | ||
None |
| #ecb400 | None | ||
None |
| #92dcb7 | None | ||
None |
| #d9fdd3 | None | ||
None |
| #cfefdf | None | ||
None |
| #d5e6cc | None | ||
None |
| #c0d0c0 | None | ||
None |
| #ace4c8 | None | ||
None |
| #dbfebc | None | ||
None |
| #bbffdd | None | ||
None |
| #e1f0d8 | None | ||
None |
| #d6fe9a | None | ||
None |
| #95ffca | None | ||
None |
| #cdffd9 | None | ||
None |
| #a6fcaa | None | ||
None |
| #cbefce | None | ||
None |
| #9acefe | None | ||
None |
| #69cf9c | None | ||
None |
| #bddbf1 | None | ||
None |
| #b8eac3 | None | ||
None |
| #90a565 | None | ||
None |
| #b7d9cc | None | ||
None |
| #a7ba86 | None | ||
None |
| #a5aaad | None | ||
None |
| #8dbecd | None | ||
None |
| #bbc0c5 | None | ||
None |
| #56e0fc | None | ||
None |
| #43aff9 | None | ||
None |
| #6bc3ff | None | ||
None |
| #38b4b1 | None | ||
None |
| #60ccbf | None | ||
None |
| #bfe3dc | None | ||
None |
| #cddeff | None | ||
None |
| #019ccd | None | ||
None |
| #9abfc0 | None | ||
None |
| #c0aeb6 | None | ||
None |
| #b99598 | None | ||
None |
| #d9c2a3 | None | ||
None |
| #820041 | None | ||
None |
| #6e4909 | None | ||
None |
| #fc6e7c | None | ||
None |
| #ffc1b7 | None | ||
None |
| #ffe1e8 | None | ||
None |
| #e45891 | None | ||
None |
| #ffeff3 | None | ||
None |
| #dd2972 | None | ||
None |
| #ffd1dc | None | ||
None |
| #f9b5bb | None | ||
None |
| #f8beae | None | ||
None |
| #ffb3c5 | None | ||
None |
| #ff6f6b | None | ||
None |
| #fc5262 | None | ||
None |
| #e979a6 | None | ||
None |
| #fcb6b6 | None | ||
None |
| #ffa7bc | None | ||
None |
| #f43c6c | None | ||
None |
| #fb2338 | None | ||
None |
| #f41a87 | None | ||
None |
| #ff6388 | None | ||
None |
| #ff275a | None | ||
None |
| #ff819f | None | ||
None |
| #ffa99d | None | ||
None |
| #e81c00 | None | ||
None |
| #ff3317 | None | ||
None |
| #d60000 | None | ||
None |
| #ac0000 | None | ||
None |
| #ff6f5b | None | ||
None |
| #e377ad | None | ||
None |
| #eda7ca | None | ||
None |
| #e993be | None | ||
None |
| #ffd6d1 | None | ||
None |
| #ffbfce | None | ||
None |
| #ff95ae | None | ||
None |
| #ff6f91 | None | ||
None |
| #ff1b51 | None | ||
None |
| #e80037 | None | ||
None |
| #ce0031 | None | ||
None |
| #b0002a | None | ||
None |
| #c1010a | None | ||
None |
| #940023 | None | ||
None |
| #a30109 | None | ||
None |
| #750107 | None | ||
None |
| #ffb7de | None | ||
None |
| #ffc3e4 | None | ||
None |
| #ffd1ea | None | ||
None |
| #ffc3f8 | None | ||
None |
| #ffe5f3 | None | ||
None |
| #ffe0de | None | ||
None |
| #f9d3d3 | None | ||
None |
| #fff3c9 | None | ||
None |
| #ffefd9 | None | ||
None |
| #ffe5c3 | None | ||
None |
| #ffd59d | None | ||
None |
| #ffa227 | None | ||
None |
| #ffc16f | None | ||
None |
| #f48b00 | None | ||
None |
| #fedc7e | None | ||
None |
| #fecc68 | None | ||
None |
| #fec62a | None | ||
None |
| #fecdac | None | ||
None |
| #feb786 | None | ||
None |
| #fea060 | None | ||
None |
| #fe8736 | None | ||
None |
| #fe7518 | None | ||
None |
| #eb6001 | None | ||
None |
| #c95201 | None | ||
None |
| #b14801 | None | ||
None |
| #933c01 | None | ||
None |
| #ecd5c6 | None | ||
None |
| #ddb397 | None | ||
None |
| #d39d79 | None | ||
None |
| #c68050 | None | ||
None |
| #a96537 | None | ||
None |
| #c24100 | None | ||
None |
| #5f391f | None | ||
None |
| #854f2b | None | ||
None |
| #a03500 | None | ||
None |
| #6e2500 | None | ||
None |
| #a7a7ff | None | ||
None |
| #eaafff | None | ||
None |
| #7dff7d | None | ||
None |
| #c9ffc9 | None | ||
None |
| #e6cdff | None | ||
None |
| #9fff9f | None | ||
None |
| #e9ffe9 | None | ||
None |
| #0000ff | None | ||
None |
| #ff57ff | None | ||
None |
| #ff8dff | None | ||
None |
| #ffa7ff | None | ||
None |
| #fe6700 | None | ||
None |
| #ff0000 | None | ||
None |
| #b93b68 | None | ||
None |
| #872b4c | None | ||
None |
| #c9557e | None | ||
None |
| #008000 | None | ||
None |
| #b4cfe4 | None | ||
None |
| #dbdbe7 | None | ||
None |
| #ededf3 | None | ||
None |
| #c0c0c0 | None | ||
None |
| #b1b1b1 | None | ||
None |
| #cacadc | None | ||
None |
| #a2a2c0 | None | ||
None |
| #b6b6ce | None | ||
None |
| #969696 | None | ||
None |
| #a337fd | None | ||
None |
| #ecd6fe | None | ||
None |
| #e0bcfe | None | ||
None |
| #d5a4fe | None | ||
None |
| #c886fe | None | ||
None |
| #ccb7ff | None | ||
None |
| #b395ff | None | ||
None |
| #9063ff | None | ||
None |
| #9f00ca | None | ||
None |
| #7b009c | None | ||
None |
| #6a006a | None | ||
None |
| #ce9dff | None | ||
None |
| #a449ff | None | ||
None |
| #8103ff | None | ||
None |
| #46008c | None | ||
None |
| #005c00 | None | ||
None |
| #84613e | None | ||
None |
| #d0cbb0 | None | ||
None |
| #b0a778 | None | ||
None |
| #887f50 | None | ||
None |
| #ac7f50 | None | ||
None |
| #6d5033 | None | ||
None |
| #64020b | None | ||
None |
| #887f50 | None |
There are also default timescales:
time = Legend.default_timescale()
time[:10]
hatch | component | colour | width | ||
---|---|---|---|---|---|
None |
| #6fdaed | None | ||
None |
| #f6ec39 | None | ||
None |
| #fef691 | None | ||
None |
| #f2f902 | None | ||
None |
| #fedd2d | None | ||
None |
| #fef1e0 | None | ||
None |
| #feefb8 | None | ||
None |
| #fef1d6 | None | ||
None |
| #fef1d6 | None | ||
None |
| #fef0cc | None |
Legend from image#
If you have an image of a legend (just the colours), Striplog
will have a go at reading colours from it.
from IPython.display import Image
Image('z_Lithology_legend_gapless2.png', width=15)
liths = [
'Conglomerate',
'Sandstone',
'Sandstone',
'Sandstone',
'Sandstone',
'Sandstone',
'Siltstone',
'Siltstone',
'Heterolithic',
'Heterolithic',
'Mudstone',
'Mudstone',
'Limestone',
'Dolomite',
'Anhydrite',
'Halite',
'Coal',
'Volcanic',
'NULL',
]
colours = [
None,
'Grey',
'Red',
'Grey',
'Grey',
'Red',
'Grey',
'Red',
'Grey',
'Red',
'Grey',
'Red',
None,
None,
None,
None,
None,
None,
None,
]
components = [Component({'lithology': l, 'colour': c}) for l, c in zip(liths, colours)]
Legend.from_image('z_Lithology_legend_gapless2.png', components)
hatch | component | colour | width | ||||
---|---|---|---|---|---|---|---|
None |
| #86f0b6 | None | ||||
None |
| #ffe040 | None | ||||
None |
| #ffd073 | None | ||||
None |
| #f2ff42 | None | ||||
None |
| #f7e9a6 | None | ||||
None |
| #ffdbba | None | ||||
None |
| #a68374 | None | ||||
None |
| #a1655a | None | ||||
None |
| #dbd6bc | None | ||||
None |
| #dbc9bc | None | ||||
None |
| #666666 | None | ||||
None |
| #664a4a | None | ||||
None |
| #a6d1ff | None | ||||
None |
| #a657fa | None | ||||
None |
| #ff99cc | None | ||||
None |
| #ff96f6 | None | ||||
None |
| #363434 | None | ||||
None |
| #ff4c4a | None | ||||
None |
| #ffffff | None |
Querying a legend#
The legend is basically a query table. We can ask the Legend what colour to use for a given Rock object:
legend.get_colour(rock)
'#eeeeee'
rock3 = Component({'colour': 'red',
'grainsize': 'vf-f',
'lithology': 'sandstone'})
legend.get_colour(rock3)
'#ffdbba'
Legend.random(rock3)
hatch | component | colour | width | ||||||
---|---|---|---|---|---|---|---|---|---|
None |
| #f05f51 | 1.0 |
Sometimes we also want to use a width for a given lithology:
legend.get_width(rock3)
3.0
We can also ask the legend which Rock is represented by a particular colour. (I doubt you’d ever really need to do this, but I had to implement this to allow you to make a Striplog
from an image: it looks up the rocks to use by colour.)
legend.get_component('#f7e9a6')
lithology | sandstone |
colour | grey |
grainsize | vf-f |
The Legend
behaves more or less like a list, so we can index into it:
legend[3:5]
hatch | component | colour | width | ||
---|---|---|---|---|---|
None |
| #ff4c4a | 2.0 | ||
None |
| #86f0b6 | 5.0 |
Legend
s can plot themselves.
legend.plot()
Sometimes you don’t want to have to make a legend, so you can use a random one. Just pass a list of Component
s…
# We'll scrape a quick list of 7 components from the default legend:
c = [d.component for d in legend[:7]]
l = Legend.random(c)
l.plot()
There is a default colour table for geological timescales too… it’s based on the Wikipedia’s colour scheme for the geological timetable.
time[74:79].plot(fmt="{age!t}") # Pass a format for proper case
©2022 Agile Geoscience. Licensed CC-BY. striplog.py