Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Cittena
cittena
Commits
091de338
Commit
091de338
authored
Jan 26, 2017
by
Niels-Oliver Walkowski
Browse files
Merge branch 'dev'
parents
a334c077
0badb2c3
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
README.md
View file @
091de338
# Itten
Itten
=====
Itten is a python library to analyse and visualize color dynamics within moving
image files or frames that were extracted from moving image files.
Optimization
============
Eventuell kann ich einen ganzen Film oder zumindest die Kontrastwerte eines
ganzen Films speichern, wenn ich nur die Histogramme speicher (256
*
frames)
ToDo
====
[]
`MultivariatePlot`
muss noch auf die selbe Simplizität wie
`UnivariatePlot`
umgestellt werden
[] gettter und setter für Frames.start setzen und das Rekursionsproblem lösen
[x] Bisher funktioniert nur der LightDark Contrast, andere Kontraste
implementieren
[] frame_range aus UnivariatePlot in Frames outsourcen und Folgen in allen
Klassen beseitigen. (wieder rekursives Aufrufproblem in __init__
[] Möglichkeit view instanzen zu picklen (siehe Abschnitt)
[] Visualisierung innerhalb derer die Pixel des Ursprungsbildes entlang der
Achse des zu Grunde liegenden Kontrastwertes sortiert werden
[] helper function zur Umrechnung von Frames in Zeit und umgekehrt (mit Aufruf
von mplayer, Bildbetrachter an der entsprechenden Stell)
[] Sequence Daten (Plot) Clustern mit K-Means statt descriptiv zu evaluieren
[] Mittels Fancy Indexing, die Bereiche in eine View isolieren, die ich für
ein bestimmtes Muster identifiziert habe und dann statistisch beschreiben
Möglichkeiten View instanzen zu picklen
---------------------------------------
bereits ausprobiert, jedoch kan die Frames Instanz
`_frames`
die von der view
Instanz benötigt wird nach dem unpickling nicht aufgerufen werden, so dass
meine Methoden nicht mehr funktionieren. Zur Lösung der Problematik:
<http://stackoverflow.com/questions/3614379/attributeerror-when-unpickling-an-object>
<http://stackoverflow.com/questions/3363281/attributeerror-module-object-has-no-attribute-when-using-cpickle>
Session.vim
deleted
100644 → 0
View file @
a334c077
let
SessionLoad
=
1
let
s:so_save
=
&
so
|
let
s:siso_save
=
&
siso
|
set
so
=
0
siso
=
0
let
v
:
this_session
=
expand
(
"<sfile>:p"
)
silent
only
cd
~
/Research/
Projects
/Cinemetrics/
Itten
if
expand
(
'%'
)
==
''
&&
!
&
modified
&&
line
(
'$'
)
<=
1
&&
getline
(
1
)
==
''
let
s:wipebuf
=
bufnr
(
'%'
)
endif
set
shortmess
=
aoO
badd
+
60
testing/ittennb
.
py
badd
+
17
itten/movie
.
py
badd
+
25
itten/contrasts
.
py
badd
+
16
itten/helpers
.
py
badd
+
1023
term
:
//
.
//
20282
:
/usr/
bin
/zsh\ ;\#neoterm
-1
argglobal
silent
!
argdel *
edit
testing/ittennb
.
py
set
splitbelow
splitright
wincmd
t
set
winheight
=
1
winwidth
=
1
argglobal
setlocal
fdm
=
manual
setlocal
fde
=
0
setlocal
fmr
={{{,}}}
setlocal
fdi
=
#
setlocal
fdl
=
0
setlocal
fml
=
1
setlocal
fdn
=
20
setlocal
fen
silent
!
normal
!
zE
let
s:l
=
1
-
((
0
*
winheight
(
0
)
+
34
)
/
68
)
if
s:l
<
1
|
let
s:l
=
1
|
endif
exe
s:l
normal
!
zt
1
normal
!
0
tabnext
1
if
exists
(
's:wipebuf'
)
&&
getbufvar
(
s:wipebuf
,
'&buftype'
)
isnot#
'terminal'
silent
exe
'bwipe '
.
s:wipebuf
endif
unlet
!
s:wipebuf
set
winheight
=
1
winwidth
=
20
shortmess
=
filnxtToO
let
s:sx
=
expand
(
"<sfile>:p:r"
).
"x.vim"
if
file_readable
(
s:sx
)
exe
"source "
.
fnameescape
(
s:sx
)
endif
let
&
so
=
s:so_save
|
let
&
siso
=
s:siso_save
let
g:this_session
=
v
:
this_session
let
g:this_obsession
=
v
:
this_session
let
g:this_obsession_status
=
2
doautoall
SessionLoadPost
unlet SessionLoad
" vim: set ft=vim :
itten/contrasts.py
View file @
091de338
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import
numpy
as
np
import
cv2
as
cv
# TODO create generic class
# TODO import as cv
import
cv2
import
numpy
as
np
from
.helpers
import
luminance
from
copy
import
deepcopy
# subclassing numpy ndarray
# Vorgehen: https://docs.scipy.org/doc/numpy/user/basics.subclassing.html
# resize Probleme https://sourceforge.net/p/numpy/mailman/message/12594801/
# andere ownership Probleme könne angeblich mit out= gelöst werden
# "Use __new__ when you need to control the creation of a new instance.
# Use __init__ when you need to control initialization of a new instance."
class
View
(
np
.
ndarray
):
"""Core class for the representation of colour contrasts in Movies
View is the basis class for specific ways to represent colour contrasts.
It does hold the definitions of contrasts itself. Objects of class View
subclass the numpy array class and hence inherit numpy methods. However,
it is not recommended to use functions which manipulate the array in
terms of structure. In this case some of the additional functions which
are implemented by this class and its subclasses might not lead to
reasonable results.
Attributes:
TODO Docstring komplettieren und Verfahren überprüfen
"""
def
__new__
(
cls
,
frames
,
input_array
=
None
):
"""instantiates the view class
instantiation complies with the recommendation for subclassing
numpy.ndarray
Parameters
----------
frames : itten.movie.Frames
input_array : itten.contrasts.View # TODO wie schaffte np lower case object
contrast : String # Modifizieren Channel Integer to String
frame_step : Int
savefig : Boolean
Returns
-------
Object : View
Empty numpy.ndarray of type View
"""
obj
=
input_array
if
type
(
obj
)
==
np
.
ndarray
:
obj
=
np
.
asarray
(
input_array
,
dtype
=
np
.
uint8
).
view
(
cls
).
copy
()
else
:
input_array
=
np
.
zeros
((
0
),
dtype
=
np
.
uint8
)
obj
=
np
.
asarray
(
input_array
).
view
(
cls
).
copy
()
obj
.
_frames
=
frames
obj
.
_contrast
=
2
obj
.
_frame_step
=
10
obj
.
_bins
=
256
return
obj
def
__array_finalize__
(
self
,
obj
):
if
obj
is
None
:
return
self
.
_frames
=
getattr
(
obj
,
'_frames'
,
None
)
self
.
_contrast
=
getattr
(
obj
,
'_contrast'
,
None
)
self
.
_frame_step
=
getattr
(
obj
,
'_frame_step'
,
None
)
self
.
_bins
=
getattr
(
obj
,
'_bins'
,
None
)
def
__array_wrap__
(
self
,
out_arr
,
context
=
None
):
return
np
.
ndarray
.
__array_wrap__
(
self
,
out_arr
,
context
)
# subclassing subclass of numpy http://stackoverflow.com/questions/7342637/how-to-subclass-a-subclass-of-numpy-ndarray
# TODO es gibt noch das Problem, dass numpy nach mehreren Berechnungen von drive eine max recursion Warnung ausgiebt, warum? Brauche ich __del__
class
VHistStack
(
View
):
def
__new__
(
cls
,
frames
,
input_array
=
None
):
"""Represents a movie contrast in terms of stacked histograms
For each defined frame a histogram is calculated and each bin that
exceeds threshold is considered in the output array
Parameters
----------
bins : Int
Number of bins for the calculation of the histogram
thrsh : Int
Threshhold defining the number of pixels a bin needs to contain
to be considered in the result
Returns
-------
Object : VHistStack
VHistStack is a 2-dimensional numpy array which contains
the frame number, the bin number and a quantifier which
represents the relative weight of the bin in the frame
"""
class
Contrast
(
object
):
"""Base class for color contrasts"""
def
__init__
(
self
,
img
):
self
.
_img
=
img
class
LightDark
(
Contrast
):
"""docstring for LightDark"""
def
__init__
(
self
,
img
,
method
=
'luminance'
):
super
(
LightDark
,
self
).
__init__
(
img
)
obj
=
View
.
__new__
(
cls
,
frames
,
input_array
=
input_array
)
obj
.
_threshold
=
60000
return
obj
meth
=
getattr
(
LightDark
,
method
)
self
.
ctrst
=
meth
(
self
)
def
__array_finalize__
(
self
,
obj
):
if
obj
is
None
:
return
View
.
__array_finalize__
(
self
,
obj
)
self
.
_threshold
=
getattr
(
obj
,
'_threshold'
,
None
)
def
luminance
(
self
):
"""Creates light/dark values using luminance quantifiers for RGB
# TODO jetzt ausschließlich mit self numpy rechnen statt mit contrast_points liste
def
populate
(
self
,
ctrst
=
2
,
frm_stp
=
10
,
bins
=
16
,
thrsh
=
60000
,
start
=
1
,
end
=
0
):
"""doc (aus __new__ zusammentragen)
The array has the same dimensions as the image. However the third
does only have the size 1 which contains the luminance value
"""
# Luminance Faktoren nach http://introcs.cs.princeton.edu/python/31datatype/luminance.py.html
luminance_factors
=
np
.
array
([.
114
,
.
587
,
.
299
])
# Erzeugung eines eindimensionalen Arrays für die effizientere Berechnung
self
.
_img
=
np
.
multiply
(
self
.
_img
,
luminance_factors
)
# addiert alle Werte auf einer bestimmten Achse
luminances
=
np
.
sum
(
self
.
_img
,
axis
=
2
)
luminances
=
luminances
.
astype
(
np
.
uint8
,
copy
=
True
)
return
luminances
def
value
(
self
):
"""Creates light/dark values using the value channel in HSV"""
img
=
cv
.
cvtColor
(
self
.
_img
,
cv
.
COLOR_BGR2HSV
)
values
=
img
[:,
:,
2
].
copy
()
return
values
def
lightness
(
self
):
"""Creates light/dark values using the value channel in HSV"""
img
=
cv
.
cvtColor
(
self
.
_img
,
cv
.
COLOR_BGR2HLS
)
lightness
=
img
[:,
:,
1
].
copy
()
return
lightness
class
Saturation
(
Contrast
):
"""docstring for Saturation"""
def
__init__
(
self
,
img
,
method
=
'saturation'
):
super
(
Saturation
,
self
).
__init__
(
img
)
meth
=
getattr
(
Saturation
,
method
)
self
.
ctrst
=
meth
(
self
)
def
saturation
(
self
):
"""docstring for saturation"""
img
=
cv
.
cvtColor
(
self
.
_img
,
cv
.
COLOR_BGR2HSV
)
saturations
=
img
[:,
:,
1
].
copy
()
return
saturations
def
chroma
(
self
):
"""docstring for chroma"""
pass
class
Hue
(
Contrast
):
"""docstring for Saturation"""
def
__init__
(
self
,
img
,
method
=
'hue'
):
super
(
Hue
,
self
).
__init__
(
img
)
meth
=
getattr
(
Hue
,
method
)
self
.
ctrst
=
meth
(
self
)
def
hue
(
self
):
"""docstring for hue"""
img
=
cv
.
cvtColor
(
self
.
_img
,
cv
.
COLOR_BGR2HSV
)
hues
=
img
[:,
:,
0
].
copy
()
return
hues
# set class properties
self
.
_contrast
=
ctrst
self
.
_frame_step
=
frm_stp
self
.
_bins
=
bins
self
.
_threshold
=
thrsh
# TODO dafür müssen erst getters und setters in movie.frames definiert werden
# slef._frames.start = start
# slef._frames.end = end
contrast_points
=
[]
# pwd list sollte in Frames sein und hier nur durchlaufen werden
for
frm_nr
in
range
(
self
.
_frames
.
start
,
self
.
_frames
.
end
,
self
.
_frame_step
):
pwd
=
self
.
_frames
.
folder
+
self
.
_frames
.
prefix
+
str
(
frm_nr
)
+
'.png'
img
=
cv2
.
imread
(
pwd
)
# BGR
# TODO Dictionary um Parameter auf Kontrast Funktion zu mappen
# so wie hier für 2 das ist die Referznimplementierung
# luminances gibt ein Bild mit den luminanz werten in der
# 3. Dimension zurück
if
self
.
_contrast
==
2
:
luminances
=
luminance
(
img
)
hist_value
,
_
=
np
.
histogram
(
luminances
.
flatten
(),
bins
=
self
.
_bins
,
range
=
(
0
,
256
))
else
:
img_hsv
=
cv2
.
cvtColor
(
img
,
cv2
.
COLOR_BGR2HSV_FULL
)
hist_value
=
cv2
.
calcHist
([
img_hsv
],
[
self
.
_contrast
],
None
,
[
16
],
[
0
,
256
])
for
bin_index
,
point
in
enumerate
(
hist_value
):
if
point
>
self
.
_threshold
:
contrast_points
.
append
((
frm_nr
,
bin_index
,
int
(
point
)))
contrast_points
=
np
.
asarray
(
contrast_points
,
np
.
uint8
)
shape
=
contrast_points
.
shape
self
.
resize
(
shape
,
refcheck
=
False
)
self
[:,
:]
=
contrast_points
return
deepcopy
(
self
)
# TODO does not create a new object
itten/movie.py
View file @
091de338
...
...
@@ -2,10 +2,13 @@
# -*- coding: utf-8 -*-
from
pathlib
import
Path
# TODO wie kann ich third-party module nach außen verstecken
import
pickle
# TODO Ist der import aus dem selben Pakte so korrekt?
from
.
import
helpers
from
.
import
contrasts
from
.
import
views
from
.
import
visuals
import
numpy
as
np
# zum Problem mit privaten und öffentlichen Eigenschaften http://www.python-course.eu/python3_properties.php und 'Fluent Python' relativ weit vorne
# numpy gibt beim Versuch zB. size zu schreiben auch ein AttributeError() aus.
...
...
@@ -15,14 +18,125 @@ class Movie(object):
self
.
_frames
=
Frames
(
folder
,
prefix
)
self
.
fsize
=
self
.
_frames
.
frm_cnt
# TODO Warum ist die hier?
def
light_dark
(
self
):
"""compute the light/dark contrast of the movie """
light_dark_ctrst
=
contrast
s
.
LightDark
(
self
.
_frames
)
light_dark_ctrst
=
view
s
.
LightDark
(
self
.
_frames
)
return
light_dark_ctrst
.
hist_vstack
()
def
describe
(
self
,
desc
=
False
,
start
=
1
,
end
=
0
,
stp
=
5
):
"""Calculates each feature provided by Itten for the movie instance
Summary values will be returned in a python dictionary. Contrast
sequences will not be returned due to save memory. The method which
will be used to compute each contrast is the contrast class' default
method. Instead the will be plotted using Itten Sequence Plots. More
precisely MultivariatePlot and UnivariatePlot will be stored on disk
for each contrast type. The filename follows the Pattern prefix +
contrast.
Parameters
----------
start: Int which defines the start frame for the description
end: Int which defines the end frame for the description (0 defines
the unknown end frame)
Returns
-------
Dictionary: Dictionary which contains summarizing statistics The
Dictionary keys carry the names of the type of
summarization. For each contrast it contains: min, max,
mean, median, 25, 75, standard deviation, variance. And for
each of this values the same set of values are computed.
ToDo
----
- outsource summary/feature loop to function which can be accessed
by the view class
- pickle view data
"""
# set properties of the current function call
self
.
_frames
.
start
=
start
self
.
_frames
.
end
=
end
prefix
=
self
.
_frames
.
prefix
if
not
(
desc
):
desc
=
'Frame '
+
str
(
start
)
+
' bis '
+
str
(
end
)
# Summary Dictionary
title
=
prefix
[:
-
1
]
summary
=
{
title
:
{}}
# available contrasts
contrasts
=
[
'saturation'
,
'light_dark'
]
# compute all available statistics for each contrast
for
ctrst
in
contrasts
:
summary
[
title
][
ctrst
]
=
{}
# compute multivariatee contrast representation
multivariate
=
views
.
MultivariateSequence
(
self
.
_frames
)
multivariate
.
populate
(
ctrst
=
ctrst
,
frm_stp
=
stp
+
2
)
# TODO: pickle instance instead of just deleating it!
# plot multivariate view
vis
=
visuals
.
MultivariatePlot
(
multivariate
)
vis
.
plot
(
multivariate
)
header
=
prefix
[:
-
1
]
+
' MultivariatePlot for '
+
ctrst
+
' - '
+
desc
filename
=
prefix
+
'multivariateplot_'
+
ctrst
+
'_'
+
desc
vis
.
saveplt
(
fname
=
filename
,
title
=
header
)
# compute summarizations for current contrast
univariate
=
views
.
UnivariateSequence
(
self
.
_frames
)
# TODO Workaround, becaus frm_stp is not part of Frames classbut
# view class so when I instantiate vis below it defaults to the
# __init__ value 10 and not the value set by the call of describe.
# This leads to a matplotlib error
univariate
.
_frame_step
=
stp
# instantiate plot for all univariate summarizations
vis
=
visuals
.
UnivariatePlot
(
univariate
)
# summarizing methods of univariate class
summarizations
=
[
'seqmean'
,
'seqmad'
]
# TODO Varianz funktioniert so nicht
for
feature
in
summarizations
:
# compute summarizations for given univariate value
getattr
(
univariate
,
feature
)(
ctrst
=
ctrst
,
frm_stp
=
stp
)
# TODO Pickle current instance state
# describe current feature by summarizing statistics
summary
[
title
][
ctrst
][
feature
[
3
:]]
=
{
'minv'
:
int
(
univariate
.
min
()),
'maxv'
:
int
(
univariate
.
max
()),
'mean'
:
int
(
univariate
.
mean
()),
'median'
:
int
(
np
.
median
(
univariate
)),
'perc25'
:
int
(
np
.
percentile
(
univariate
,
25
)),
'perc75'
:
int
(
np
.
percentile
(
univariate
,
75
)),
'std'
:
int
(
univariate
.
std
()),
'var'
:
int
(
univariate
.
var
())
}
# plot current summarization current univariate contrast plot
vis
.
plot
(
univariate
)
# save univariate plot
header
=
prefix
[:
-
1
]
+
' UnivariatePlot for '
+
ctrst
+
' - '
+
desc
filename
=
self
.
_frames
.
prefix
+
'univariateplot_'
+
ctrst
+
'_'
+
desc
vis
.
saveplt
(
fname
=
filename
,
title
=
header
)
with
open
(
prefix
[:
-
1
]
+
'_summary.pickle'
,
'wb'
)
as
f
:
pickle
.
dump
(
summary
,
f
)
return
summary
class
Frames
(
object
):
# TODO getters und setters für start und end setzen
# TODO frm_stp sollte definitiv Teil der Frames Klasse werden
"""Parses movie frames properties"""
def
__init__
(
self
,
folder
,
prefix
,
start
=
1
,
end
=
0
):
self
.
folder
=
folder
...
...
@@ -30,8 +144,40 @@ class Frames(object):
self
.
frames
=
self
.
get_frame_list
()
self
.
frm_length
=
self
.
count_total_frames
()
self
.
start
=
start
self
.
end
=
self
.
_get_end_frame
(
end
)
self
.
frm_cnt
=
self
.
count_frames
()
self
.
end
=
end
self
.
frm_cnt
=
0
# TODO start als property erzeugt bisher eine Endlosschleife wei
# count_frames sart und end brauchen und so gegenseitig sart und end nicht
# gesetzt wird
@
property
def
end
(
self
):
return
self
.
__end
@
end
.
setter
def
end
(
self
,
nr
):
if
nr
==
0
:
self
.
__end
=
self
.
frm_length
self
.
frm_cnt
=
self
.
count_frames
()
elif
nr
>
self
.
frm_length
:
self
.
__end
=
self
.
frm_length
-
1
self
.
frm_cnt
=
self
.
count_frames
()
elif
nr
<
self
.
start
:
self
.
__end
=
self
.
start
+
1
self
.
frm_cnt
=
self
.
count_frames
()
else
:
self
.
__end
=
nr
self
.
frm_cnt
=
self
.
count_frames
()
@
property
def
frm_cnt
(
self
):
return
self
.
__frm_cnt
@
frm_cnt
.
setter
def
frm_cnt
(
self
,
nr
):
count
=
self
.
count_frames
()
self
.
__frm_cnt
=
count
def
get_frame_list
(
self
):
frm_path
=
Path
(
self
.
folder
)
...
...
itten/views.py
0 → 100644
View file @
091de338
This diff is collapsed.
Click to expand it.
itten/visuals.py
0 → 100644
View file @
091de338
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import
matplotlib.pyplot
as
plt
import
matplotlib.ticker
as
plticker
import
numpy
as
np
class
SequencePlot
(
object
):
"""Key class for visualizations with two axis"""
def
__init__
(
self
,
view
,
width
=
40
,
height
=
3
):
self
.
width
=
width
self
.
height
=
height
self
.
_x
=
self
.
get_xpos
(
view
)
# outsourcen in Frames Class und dann hier löschen
def
get_xpos
(
self
,
view
):
"""calculate frame numbers for x-ticks"""
# TODO Die Frame No. Range könnte ich auch besser zu einer Methode von Frames machen
return
[
nr
for
nr
in
range
(
view
.
_frames
.
start
,
view
.
_frames
.
end
,
view
.
_frame_step
)]
# um X-Achse Minuten anzeigen zu lassen
def
_timelabels
(
self
,
val
,
pos
):
min
,
sec
=
divmod
(
int
(
val
),
60
)
timelabel
=
"{0}:{1:02d}"
.
format
(
min
,
sec
)
return
timelabel
# TODO styling und plotten sind hier noch etwas zusammengemischt
def
ittenstyle
(
self
,
ax
,
view
):
plt
.
style
.
use
(
'ggplot'
)
fig_coef
=
self
.
width
/
self
.
height
tick_cnt
=
fig_coef
/
0.3605405405
tick_step
=
int
(
view
.
_frames
.
frm_cnt
/
tick_cnt
)
# loc = plticker.MultipleLocator(base=tick_freq) # this locator puts ticks at regular intervals (0.0005)
loc
=
plticker
.
FixedLocator
(
range
(
0
,
view
.
_frames
.
end
,
tick_step
))
fmt
=
plticker
.
FuncFormatter
(
self
.
_timelabels
)
ax
.
xaxis
.
set_major_locator
(
loc
)
ax
.
xaxis
.
set_major_formatter
(
fmt
)
ax
.
set_xlim
(
view
.
_frames
.
start
-
20
,
view
.
_frames
.
end
+
20
)
# Beschriftung der Y-Achse
# TODO funktioniert nicht richtig
ax
.
set_ylim
(
-
1
,
view
.
_bins
+
1
)
loc
=
plticker
.
FixedLocator
(
range
(
0
,
view
.
_bins
+
1
,
int
(
view
.
_bins
/
8
)))
ax
.
yaxis
.
set_major_locator
(
loc
)
# TODO mit iter_ticks evtl noch die angegebenen Sekunden auf base 60 setzen
# obere x-achse mit zeitlich versetzten werten
axt
=
ax
.
twiny
()
axt
.
set_xlim
(
ax
.
get_xlim
())
axt
.
set_ylim
(
ax
.
get_ylim
())
# loc = plticker.MultipleLocator(base=tick_freq)
# loc = plticker.LinearLocator(20)
loc
=
plticker
.
FixedLocator
(
range
(
int
(
tick_step
/
2
),
view
.
_frames
.
end
,
tick_step
))
fmt
=
plticker
.
FuncFormatter
(
self
.
_timelabels
)
axt
.
xaxis
.
set_major_locator
(
loc
)
axt
.
xaxis
.
set_major_formatter
(
fmt
)
ax
.
set_axis_bgcolor
((
1
,
1
,
1
))
# TODO: gradient
chn_label
=
view
.
_contrast
ax
.
set_ylabel
(
chn_label
,
{
'fontsize'
:
8
})
ax
.
set_xlabel
(
'Time'
,
{
'fontsize'
:
8
},
y
=
0.5
)
ax
.
yaxis
.
grid
(
False
)
axt
.
yaxis
.
grid
(
False
)
ax
.
tick_params
(
length
=
0
)
axt
.
tick_params
(
length
=
0
)
ax
.
xaxis
.
grid
(
c
=
(
0.90
,
0.90
,
0.90
))
axt
.
xaxis
.
grid
(
c
=
(
0.90
,
0.90
,
0.90
))
return
(
ax
,
axt
)
# TODO Überführbar in Superclass?
# evtl. auch eher feature drer View Klasse
# TODO self._x sollte eine array sein
def
_vlines
(
self
,
view
,
mark
,
mark_gt
,
mark_lt
):
npx
=
np
.
array
(
self
.
_x
)
if
mark_gt
:
poss
=
npx
[
view
>
mark_gt
]
for
pos
in
poss
:
self
.
_ax
.
axvline
(
pos
,
color
=
'#a6e22e'
,
alpha
=
0.4
,
linewidth
=
3
)
if
mark_lt
:
poss
=
npx
[
view
<
mark_lt
]
for
pos
in
poss
:
self
.
_ax
.
axvline
(
pos
,
color
=
'#f92672'
,
alpha
=
0.4
,
linewidth
=
3
)
if
mark
:
for
pos
in
mark
:
print
(
self
.
_ax
)
self
.
_ax
.
axvline
(
pos
,
color
=
'#66d9ef'
,
alpha
=
0.4
,
linewidth
=
3
)
def
saveplt
(
self
,
title
=
False
,
fname
=
'plot.png'
):
if
title
:
self
.
_ax
.
set_title
(
title
,
{
'fontsize'
:
14
},
y
=
1.18
)
self
.
fig
.
set_size_inches
(
self
.
width
,
self
.
height
)
self
.
fig
.
tight_layout
()
self
.
fig
.
savefig
(
fname
,
dpi
=
400
)