Skip to content

Commit aa86fed

Browse files
authored
Merge pull request #21 from ModelChimp/feature/custom-plots
Matplot Feature
2 parents c0fc88e + 77e4836 commit aa86fed

File tree

19 files changed

+347
-37
lines changed

19 files changed

+347
-37
lines changed

README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,44 @@ DEFAULT_FROM_EMAIL="noreply@modelchimp.com"
7272

7373

7474
### Production Deployment
75-
For production deployment, contact Karthik at karthik@modelchimp.com
75+
76+
1. Modelchimp can be deployed referring the docker-compose.local.yml with the container orchestration of your choice. If you are not using any container orchestration and want to start it manually then you can use the following command
77+
78+
```sh
79+
docker-compose -f docker-compose.local.yml up --build -d
80+
```
81+
82+
This will start the containers in daemon mode on the machine where Modelchimp resides. Modelchimp can be accessed from port 8000
83+
84+
2. (Optional) To store the data in an external postgres database. Add the following credentials to the .env file
85+
86+
```sh
87+
DB_HOST=<DB_HOST>
88+
DB_NAME=<DB_NAME>
89+
DB_USER=<DB_USER>
90+
DB_PASSWORD=<DB_PASSWORD>
91+
DBPORT=
92+
```
93+
94+
3. (Optional) To store the file assets in an s3 bucket. Add the following credentials to the .env file
95+
96+
```sh
97+
AWS_STORAGE_FLAG=True
98+
AWS_ACCESS_KEY_ID=<ID>
99+
AWS_SECRET_ACCESS_KEY=<KEY>
100+
AWS_STORAGE_BUCKET_NAME=<bucket_name>
101+
```
102+
103+
4. (Optional) To invite team members to a project. Add the following email credentials to the .env file
104+
105+
```sh
106+
EMAIL_HOST=
107+
EMAIL_HOST_USER=
108+
EMAIL_HOST_PASSWORD=
109+
EMAIL_PORT=587
110+
DEFAULT_FROM_EMAIL="noreply@modelchimp.com"
111+
```
112+
76113

77114
## Documentation
78115
- Getting Started - https://docs.modelchimp.com/#installation

client/app/components/Section/index.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,16 @@ import React from 'react';
88
import styled from 'styled-components';
99
import PropTypes from 'prop-types';
1010

11-
const Section = ({ name, style, className, children, h3 }) => (
11+
const Section = ({ name, description, style, className, children, h3 }) => (
1212
<section className={className} style={style}>
13-
{h3 ? <h3>{name}</h3> : <h2>{name}</h2>}
13+
<div class="heading-wrapper">
14+
{h3 ? <h3>{name}</h3> : <h2>{name}</h2>}
15+
16+
<p>
17+
{description}
18+
</p>
19+
</div>
20+
1421
{children}
1522
</section>
1623
);
@@ -27,13 +34,17 @@ const StyledSection = styled(Section)`
2734
margin-top: 30px;
2835
2936
h2 {
30-
border-bottom: 1px solid grey;
3137
color: grey;
3238
}
3339
3440
h3 {
41+
color: grey;
42+
}
43+
44+
.heading-wrapper {
3545
border-bottom: 1px solid grey;
3646
color: grey;
47+
margin-bottom: 20px;
3748
}
3849
`;
3950

client/app/containers/ExperimentDetail/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ export const EXPERIMENT_TAB_CHARTS = 'app/ExperimentDetail/EXPERIMENT_TAB_CHARTS
2929
export const EXPERIMENT_TAB_OBJECTS = 'app/ExperimentDetail/EXPERIMENT_TAB_OBJECTS';
3030
export const EXPERIMENT_TAB_GRIDSEARCH = 'app/ExperimentDetail/EXPERIMENT_TAB_GRIDSEARCH';
3131
export const EXPERIMENT_TAB_ASSET = 'app/ExperimentDetail/EXPERIMENT_TAB_ASSET';
32+
export const EXPERIMENT_TAB_MATPLOTS = 'app/ExperimentDetail/EXPERIMENT_TAB_MATPLOTS';

client/app/containers/ExperimentDetail/index.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import ExperimentDetailChartPage from 'containers/ExperimentDetailChartPage/Load
2121
import ExperimentDetailObjectPage from 'containers/ExperimentDetailObjectPage/Loadable';
2222
import ExperimentDetailGridSearchPage from 'containers/ExperimentDetailGridSearchPage/Loadable';
2323
import ExperimentDetailAssetPage from 'containers/ExperimentDetailAssetPage/Loadable';
24+
import ExperimentDetailMatPlotPage from 'containers/ExperimentDetailMatPlotPage/Loadable';
2425

2526
import {
2627
EXPERIMENT_TAB_METRICS,
@@ -30,6 +31,7 @@ import {
3031
EXPERIMENT_TAB_OBJECTS,
3132
EXPERIMENT_TAB_GRIDSEARCH,
3233
EXPERIMENT_TAB_ASSET,
34+
EXPERIMENT_TAB_MATPLOTS,
3335
} from './constants';
3436

3537
import { loadExperimentDetailAction,
@@ -121,6 +123,11 @@ export class ExperimentDetail extends React.Component {
121123
<FontAwesomeIcon icon="chart-line" /> Charts
122124
</Link>
123125
</Menu.Item>
126+
<Menu.Item key={EXPERIMENT_TAB_MATPLOTS}>
127+
<Link to={`${this.props.match.url}/matplot`}>
128+
<FontAwesomeIcon icon="chart-bar" /> MatPlot
129+
</Link>
130+
</Menu.Item>
124131
<Menu.Item key={EXPERIMENT_TAB_OBJECTS}>
125132
<Link to={`${this.props.match.url}/object`}>
126133
<FontAwesomeIcon icon="database" /> Objects
@@ -191,6 +198,10 @@ export class ExperimentDetail extends React.Component {
191198
path={`${this.props.match.path}/chart`}
192199
component={ExperimentDetailChartPage}
193200
/>
201+
<Route
202+
path={`${this.props.match.path}/matplot`}
203+
component={ExperimentDetailMatPlotPage}
204+
/>
194205
<Route
195206
path={`${this.props.match.path}/object`}
196207
component={ExperimentDetailObjectPage}

client/app/containers/ExperimentDetailAssetPage/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ export class ExperimentDetailAssetPage extends React.Component {
152152

153153
render() {
154154
return (
155-
<Section name="Assets">
155+
<Section name="Assets"
156+
description="Store assets such as images, text and model files from an experiment along with any meta information associated with it"
157+
>
156158
<Input placeholder="Search"
157159
onChange={this.onSearch}
158160
style={{width:'30vw', margin:'10px'}}/>

client/app/containers/ExperimentDetailChartPage/index.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,15 @@ export class ExperimentDetailChartPage extends React.Component {
4949

5050
return (
5151
<div>
52-
<Section name="Metric Chart">
52+
<Section name="Metric Chart"
53+
description="Visualize metrics captured at epoch level"
54+
>
5355
{mData &&
5456
mData.metric_list.map((e, i) => this.createMetricChart(e, i))}
5557
</Section>
56-
<Section name="Duration Chart">
58+
<Section name="Duration Chart"
59+
description="Visualize durations captured at epoch level"
60+
>
5761
{dData &&
5862
dData.tag_list.map((e, i) => this.createDurationChart(e, i))}
5963
</Section>

client/app/containers/ExperimentDetailCodePage/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ export class ExperimentDetailCodePage extends React.Component {
5757

5858

5959
return (
60-
<Section name="Code">
60+
<Section name="Code"
61+
description="Code of the current experiment"
62+
>
6163
<link rel="stylesheet" href={CodeStyle} />
6264
{content}
6365
</Section>

client/app/containers/ExperimentDetailGridSearchPage/index.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ export class ExperimentDetailGridSearchPage extends React.Component {
7777
} = this.props;
7878
const renderHTML =
7979
gridsearchData && gridsearchData.length > 0 ? (
80-
<Section name="GridSearch">
80+
<Section name="GridSearch"
81+
description="Store and Analyze the sklearn's GridSearchCV"
82+
>
8183
<ChartMenu />
8284
<Plot
8385
data={parseChartData(
@@ -100,7 +102,9 @@ export class ExperimentDetailGridSearchPage extends React.Component {
100102
</Wrapper>
101103
</Section>
102104
) : (
103-
<Section name="GridSearch">No Data</Section>
105+
<Section name="GridSearch"
106+
description="Store and analyze the sklearn's GridSearchCV"
107+
>No Data</Section>
104108
);
105109

106110
return <div>{renderHTML}</div>;
@@ -139,7 +143,7 @@ function mapDispatchToProps(dispatch) {
139143
setParamCols: paramCols => dispatch(setParamColsAction(paramCols)),
140144
setFilter: filter => dispatch(setFilterAction(filter)),
141145
onExperimentTabSelect: tabKey =>
142-
dispatch(onExperimentTabSelect(tabKey)),
146+
dispatch(onExperimentTabSelect(tabKey)),
143147
};
144148
}
145149

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
*
3+
* Asynchronously loads the component for ExperimentDetailMatPlotPage
4+
*
5+
*/
6+
7+
import loadable from 'loadable-components';
8+
9+
import LoadingIndicator from 'components/LoadingIndicator';
10+
11+
export default loadable(() => import('./index'), {
12+
LoadingComponent: LoadingIndicator,
13+
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
*
3+
* ExperimentDetailMatPlotPage actions
4+
*
5+
*/
6+
7+
import {
8+
LOAD_EXPERIMENT_DETAIL_MATPLOT,
9+
LOAD_EXPERIMENT_DETAIL_MATPLOT_SUCCESS,
10+
LOAD_EXPERIMENT_DETAIL_MATPLOT_ERROR,
11+
} from './constants';
12+
13+
export function loadExperimentMatPlotAction(modelId) {
14+
return {
15+
type: LOAD_EXPERIMENT_DETAIL_MATPLOT,
16+
modelId,
17+
};
18+
}
19+
20+
export function loadExperimentMatPlotSuccessAction(matPlotData) {
21+
return {
22+
type: LOAD_EXPERIMENT_DETAIL_MATPLOT_SUCCESS,
23+
matPlotData,
24+
};
25+
}
26+
27+
export function loadExperimentMatPlotErrorAction(error) {
28+
return {
29+
type: LOAD_EXPERIMENT_DETAIL_MATPLOT_ERROR,
30+
error,
31+
};
32+
}

0 commit comments

Comments
 (0)