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
colourgrey
grainsizevf-f
lithologysand
porosity0.123
d = {'color': '#267022',
     'component': rock,
     'width': 3
    }

decor = Decor(d)
decor
colour#267022
component
colourgrey
grainsizevf-f
lithologysand
porosity0.123
width3.0
hatchNone
from striplog import Component
r = {'colour': 'grey',
     'grainsize': 'vf-f',
     'lithology': 'sand',
     'porosity': 0.123
    }
rock = Component(r)
rock
colourgrey
grainsizevf-f
lithologysand
porosity0.123

Like Rocks, we instantiate Decors with a dict of properties:

d = {'color': '#267022',
     'component': rock,
     'width': 3
    }

decor = Decor(d)
decor
colour#267022
component
colourgrey
grainsizevf-f
lithologysand
porosity0.123
width3.0
hatchNone

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
colourgrey
grainsizevf-f
porosity0.123
lithologysand
width3.0
hatchNone

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()
../_images/03_Display_objects_17_0.png
decor.hatch = '+'
decor.plot()
../_images/03_Display_objects_18_0.png

There are the standard matplotlib hatch patterns:

hatches = "\/|+x-.o*"
for h in hatches:
    Decor({'component': Component({'hatch':h}), 'hatch': h, 'colour': '#eeeeee'}).plot()
../_images/03_Display_objects_20_0.png ../_images/03_Display_objects_20_1.png ../_images/03_Display_objects_20_2.png ../_images/03_Display_objects_20_3.png ../_images/03_Display_objects_20_4.png ../_images/03_Display_objects_20_5.png ../_images/03_Display_objects_20_6.png ../_images/03_Display_objects_20_7.png ../_images/03_Display_objects_20_8.png

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}")
../_images/03_Display_objects_22_0.png ../_images/03_Display_objects_22_1.png ../_images/03_Display_objects_22_2.png ../_images/03_Display_objects_22_3.png ../_images/03_Display_objects_22_4.png ../_images/03_Display_objects_22_5.png ../_images/03_Display_objects_22_6.png ../_images/03_Display_objects_22_7.png ../_images/03_Display_objects_22_8.png ../_images/03_Display_objects_22_9.png

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)
../_images/03_Display_objects_24_0.png

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]
hatchcomponentcolourwidth
None
lithologysandstone
colourgrey
grainsizevf-f
#f7e9a63.0
None
lithologyanhydrite
#ff99cc2.0
None
lithologyheterolithic
colourgrey
#dbd6bc3.0
None
lithologyvolcanic
#ff4c4a2.0
None
lithologyconglomerate
#86f0b65.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)
hatchcomponentcolourwidth
None
lithologysandstone
#f7e9a6None
None
lithologysandstone
#f2ff42None
None
lithologyanhydrite
#ff99ccNone
None
lithologyheterolithic
#dbd6bcNone
None
lithologyvolcanic
#ff4c4aNone
None
lithologyconglomerate
#86f0b6None
None
lithologysandstone
#ffd073None

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
hatchcomponentcolourwidth
None
lithologysandstone
colourgrey
grainsizevf-f
#f7e9a63.0
None
lithologyanhydrite
#ff99cc2.0
None
lithologyheterolithic
colourgrey
#dbd6bc3.0
None
lithologyvolcanic
#ff4c4a2.0
None
lithologyconglomerate
#86f0b65.0
None
lithologyhalite
#ff96f62.0
None
lithologysandstone
colourgrey
grainsizef-m
#f2ff424.0
None
lithologyheterolithic
colourred
#dbc9bc3.0
None
lithologysiltstone
colourgrey
#a683742.0
None
lithologydolomite
#a657fa3.0
None
lithologysandstone
colourred
grainsizec-m
#ffd0734.0
None
lithologylimestone
#a6d1ff3.0
None
lithologysandstone
colourred
grainsizevf-f
#ffdbba3.0
None
lithologysandstone
colourgrey
grainsizec-m
#ffe0404.0
None
lithologysiltstone
colourred
#a1655a2.0
None
lithologycoal
#3634341.0
None
lithologymudstone
colourred
#664a4a1.0
None
lithologymudstone
colourgrey
#6666661.0

There is also a default legend, which you can call with Legend.default() (no arguments).

Legend.default()
hatchcomponentcolourwidth
None
lithologyunconsolidated material
#fdf43fNone
None
lithologyalluvium
#ffff89None
None
lithologyflood plain
#ffffd5None
None
lithologylevee
#fffae9None
None
lithologydelta
#fffac8None
None
lithologyalluvial fan
#ffffb7None
None
lithologyalluvial terrace
#faee7aNone
None
lithologylake or marine sediment
#f4efe4None
None
lithologyplaya
#f1e5dfNone
None
lithologymud flat
#e4d0beNone
None
lithologybeach sand
#e4d8beNone
None
lithologyterrace
#fff6d9None
None
lithologyeolian material
#e0c59eNone
None
lithologydune sand
#e0d2b4None
None
lithologysand sheet
#dbcca9None
None
lithologyloess
#f5e1bdNone
None
lithologyvolcanic ash
#e0b09eNone
None
lithologymass wasting material
#cfbb8fNone
None
lithologycolluvium
#e1e3c3None
None
lithologymudflow
#e5dbb3None
None
lithologylahar
#dcd5b4None
None
lithologydebris flow
#d3ca9fNone
None
lithologylandslide
#c9be89None
None
lithologytalus
#bcaf6cNone
None
lithologyglacial drift
#bfa743None
None
lithologytill
#d2c27cNone
None
lithologymoraine
#ffeebfNone
None
lithologystratified glacial sediment
#ffe59dNone
None
lithologyglacial outwash sediment
#ffdf85None
None
lithologysub/supra-glacial sediment
#fee670None
None
lithologyglaciolacustrine sediment
#fee258None
None
lithologyglacial-marine sediment
#fedb2eNone
None
lithologybiogenic rock
#f7f3a1None
None
lithologypeat
#ffcf81None
None
lithologycoral
#ffcc99None
None
lithologyresiduum
#ffe389None
None
lithologyclay or mud
#ffdb67None
None
lithologysilt
#ffd345None
None
lithologysand
#ffcb23None
None
lithologygravel
#ecb400None
None
lithologysedimentary rock
#92dcb7None
None
lithologyclastic rock
#d9fdd3None
None
lithologymudstone
#cfefdfNone
None
lithologyclaystone
#d5e6ccNone
None
lithologybentonite
#c0d0c0None
None
lithologyshale
#ace4c8None
None
lithologyblack shale
#dbfebcNone
None
lithologyoil shale
#bbffddNone
None
lithologyargillite
#e1f0d8None
None
lithologysiltstone
#d6fe9aNone
None
lithologyfine-grained mixed clastic rock
#95ffcaNone
None
lithologysandstone
#cdffd9None
None
lithologyarenite
#a6fcaaNone
None
lithologyorthoquartzite
#cbefceNone
None
lithologycalcarenite
#9acefeNone
None
lithologyarkose
#69cf9cNone
None
lithologywacke
#bddbf1None
None
lithologygraywacke
#b8eac3None
None
lithologymedium-grained mixed clastic rock
#90a565None
None
lithologyconglomerate
#b7d9ccNone
None
lithologysedimentary breccia
#a7ba86None
None
lithologycoarse-grained mixed clastic rock
#a5aaadNone
None
lithologyolistostrome
#8dbecdNone
None
lithologymelange
#bbc0c5None
None
lithologycarbonate rock
#56e0fcNone
None
lithologylimestone
#43aff9None
None
lithologydolostone
#6bc3ffNone
None
lithologymixed carbonate/clastic rock
#38b4b1None
None
lithologymixed volcanic/clastic rock
#60ccbfNone
None
lithologyphosphorite
#bfe3dcNone
None
lithologychemical sedimentary rock
#cddeffNone
None
lithologyevaporite
#019ccdNone
None
lithologychert
#9abfc0None
None
lithologynovaculite
#c0aeb6None
None
lithologyiron formation
#b99598None
None
lithologyexhalite
#d9c2a3None
None
lithologycoal
#820041None
None
lithologymixed coal and clastic rock
#6e4909None
None
lithologyplutonic rock
#fc6e7cNone
None
lithologyaplite
#ffc1b7None
None
lithologyporphyry
#ffe1e8None
None
lithologylampophyre
#e45891None
None
lithologypegmatite
#ffeff3None
None
lithologygranitoid
#dd2972None
None
lithologyalkali-feldspar granite
#ffd1dcNone
None
lithologygranite
#f9b5bbNone
None
lithologyperaluminous granite
#f8beaeNone
None
lithologymetaluminous granite
#ffb3c5None
None
lithologysubaluminous granite
#ff6f6bNone
None
lithologyperalkaline granite
#fc5262None
None
lithologygranodiorite
#e979a6None
None
lithologytonalite
#fcb6b6None
None
lithologytrondhjemite
#ffa7bcNone
None
lithologyalkali-feldpar syenite
#f43c6cNone
None
lithologyquartz syenite
#fb2338None
None
lithologysyenite
#f41a87None
None
lithologyquartz monzonite
#ff6388None
None
lithologymonzonite
#ff275aNone
None
lithologyquartz monzodiorite
#ff819fNone
None
lithologymonzodiorite
#ffa99dNone
None
lithologyquartz diorite
#e81c00None
None
lithologydiorite
#ff3317None
None
lithologydiabase
#d60000None
None
lithologygabbroid
#ac0000None
None
lithologyquartz monzogabbro
#ff6f5bNone
None
lithologymonzogabbro
#e377adNone
None
lithologyquartz gabbro
#eda7caNone
None
lithologygabbro
#e993beNone
None
lithologynorite
#ffd6d1None
None
lithologytroctolite
#ffbfceNone
None
lithologyanorthosite
#ff95aeNone
None
lithologyalkalic intrusive rock
#ff6f91None
None
lithologynepheline syenite
#ff1b51None
None
lithologyultramafic intrusive rock
#e80037None
None
lithologyperidotite
#ce0031None
None
lithologydunite
#b0002aNone
None
lithologykimberlite
#c1010aNone
None
lithologypyroxenite
#940023None
None
lithologyhornblendite
#a30109None
None
lithologyintrusive carbonatite
#750107None
None
lithologyvolcanic rock
#ffb7deNone
None
lithologyglassy volcanic rock
#ffc3e4None
None
lithologyobsidian
#ffd1eaNone
None
lithologyvitrophyre
#ffc3f8None
None
lithologypumice
#ffe5f3None
None
lithologypyroclastic
#ffe0deNone
None
lithologytuff
#f9d3d3None
None
lithologywelded tuff
#fff3c9None
None
lithologyash-flow tuff
#ffefd9None
None
lithologyignimbrite
#ffe5c3None
None
lithologyvolcanic breccia
#ffd59dNone
None
lithologylava flow
#ffa227None
None
lithologybimodal suite
#ffc16fNone
None
lithologyfelsic volcanic rock
#f48b00None
None
lithologyalkali-feldspar rhyolite
#fedc7eNone
None
lithologyrhyolite
#fecc68None
None
lithologyrhyodacite
#fec62aNone
None
lithologydacite
#fecdacNone
None
lithologyalkali-feldspar trachyte
#feb786None
None
lithologytrachyte
#fea060None
None
lithologyquartz latite
#fe8736None
None
lithologylatite
#fe7518None
None
lithologyintermediate volcanic rock
#eb6001None
None
lithologytrachyandesite
#c95201None
None
lithologyandesite
#b14801None
None
lithologymafic volcanic rock
#933c01None
None
lithologytrachybasalt
#ecd5c6None
None
lithologybasalt
#ddb397None
None
lithologytholeite
#d39d79None
None
lithologyhawaiite
#c68050None
None
lithologyalkaline basalt
#a96537None
None
lithologyalkalic volcanic rock
#c24100None
None
lithologyphonolite
#5f391fNone
None
lithologytephrite
#854f2bNone
None
lithologyultramafitite
#a03500None
None
lithologyvolcanic carbonatite
#6e2500None
None
lithologymetamorphic rock
#a7a7ffNone
None
lithologyhornfels
#eaafffNone
None
lithologymetasedimentary rock
#7dff7dNone
None
lithologymeta-argillite
#c9ffc9None
None
lithologyslate
#e6cdffNone
None
lithologyquartzite
#9fff9fNone
None
lithologymetaconglomerate
#e9ffe9None
None
lithologymarble
#0000ffNone
None
lithologymetavolcanic rock
#ff57ffNone
None
lithologyfelsic metavolcanic rock
#ff8dffNone
None
lithologymetarhyolite
#ffa7ffNone
None
lithologykeratophyre
#fe6700None
None
lithologyintermediate metavolcanic rock
#ff0000None
None
lithologymafic metavolcanic rock
#b93b68None
None
lithologymetabasalt
#872b4cNone
None
lithologyspilite
#c9557eNone
None
lithologygreenstone
#008000None
None
lithologyphyllite
#b4cfe4None
None
lithologyschist
#dbdbe7None
None
lithologygreenschist
#ededf3None
None
lithologyblueschist
#c0c0c0None
None
lithologymica schist
#b1b1b1None
None
lithologypelitic schist
#cacadcNone
None
lithologyquartz-feldspar schist
#a2a2c0None
None
lithologycalc-silicate schist
#b6b6ceNone
None
lithologyamphibole schist
#969696None
None
lithologygranofels
#a337fdNone
None
lithologygneiss
#ecd6feNone
None
lithologyfelsic gneiss
#e0bcfeNone
None
lithologygranitic gneiss
#d5a4feNone
None
lithologybiotite gneiss
#c886feNone
None
lithologymafic gneiss
#ccb7ffNone
None
lithologyorthogneiss
#b395ffNone
None
lithologyparagneiss
#9063ffNone
None
lithologymigmatite
#9f00caNone
None
lithologyamphibolite
#7b009cNone
None
lithologygranulite
#6a006aNone
None
lithologyeclogite
#ce9dffNone
None
lithologygreisen
#a449ffNone
None
lithologyskarn
#8103ffNone
None
lithologycalc-silicate rock
#46008cNone
None
lithologyserpentinite
#005c00None
None
lithologytectonite
#84613eNone
None
lithologytectonic melange
#d0cbb0None
None
lithologytectonic breccia
#b0a778None
None
lithologycataclasite
#887f50None
None
lithologyphyllonite
#ac7f50None
None
lithologymylonite
#6d5033None
None
lithologyflaser gneiss
#64020bNone
None
lithologyaugen gneiss
#887f50None

There are also default timescales:

time = Legend.default_timescale()
time[:10]
hatchcomponentcolourwidth
None
agephanerozoic
#6fdaedNone
None
agecenozoic
#f6ec39None
None
agequaternary
#fef691None
None
agetertiary
#f2f902None
None
ageneogene
#fedd2dNone
None
ageholocene
#fef1e0None
None
agepleistocene
#feefb8None
None
ageupper pleistocene
#fef1d6None
None
agetarantian
#fef1d6None
None
agemiddle pleistocene
#fef0ccNone

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)
../_images/03_Display_objects_42_0.png
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)
hatchcomponentcolourwidth
None
lithologyConglomerate
#86f0b6None
None
lithologySandstone
colourGrey
#ffe040None
None
lithologySandstone
colourRed
#ffd073None
None
lithologySandstone
colourGrey
#f2ff42None
None
lithologySandstone
colourGrey
#f7e9a6None
None
lithologySandstone
colourRed
#ffdbbaNone
None
lithologySiltstone
colourGrey
#a68374None
None
lithologySiltstone
colourRed
#a1655aNone
None
lithologyHeterolithic
colourGrey
#dbd6bcNone
None
lithologyHeterolithic
colourRed
#dbc9bcNone
None
lithologyMudstone
colourGrey
#666666None
None
lithologyMudstone
colourRed
#664a4aNone
None
lithologyLimestone
#a6d1ffNone
None
lithologyDolomite
#a657faNone
None
lithologyAnhydrite
#ff99ccNone
None
lithologyHalite
#ff96f6None
None
lithologyCoal
#363434None
None
lithologyVolcanic
#ff4c4aNone
None
lithologyNULL
#ffffffNone

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)
hatchcomponentcolourwidth
None
colourred
grainsizevf-f
lithologysandstone
#f05f511.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')
lithologysandstone
colourgrey
grainsizevf-f

The Legend behaves more or less like a list, so we can index into it:

legend[3:5]
hatchcomponentcolourwidth
None
lithologyvolcanic
#ff4c4a2.0
None
lithologyconglomerate
#86f0b65.0

Legends can plot themselves.

legend.plot()
../_images/03_Display_objects_58_0.png

Sometimes you don’t want to have to make a legend, so you can use a random one. Just pass a list of Components…

# 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()
../_images/03_Display_objects_60_0.png

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
../_images/03_Display_objects_62_0.png

©2022 Agile Geoscience. Licensed CC-BY. striplog.py