Skip to content

Commit

Permalink
[PLOTS] added modifiable tick labels
Browse files Browse the repository at this point in the history
  • Loading branch information
hoffstadt committed Aug 13, 2020
1 parent 528bac7 commit 984da54
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 7 deletions.
18 changes: 18 additions & 0 deletions DearPyGui/include/mvMarvel.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,24 @@ namespace Marvel {
{mvPythonDataType::Integer, "xoffset"},
{mvPythonDataType::Integer, "yoffset"}
}, "Adds a point with text to a plot.", "None", "Plotting") });

parsers->insert({ "set_xticks", mvPythonParser({
{mvPythonDataType::String, "plot"},
{mvPythonDataType::Object, "label_pairs", "list of [str,float]"},
}, "Sets plots x ticks and labels", "None", "Plotting") });

parsers->insert({ "set_yticks", mvPythonParser({
{mvPythonDataType::String, "plot"},
{mvPythonDataType::Object, "label_pairs", "list of [str,float]"},
}, "Sets plots y ticks and labels", "None", "Plotting") });

parsers->insert({ "reset_xticks", mvPythonParser({
{mvPythonDataType::String, "plot"},
}, "Sets plots x ticks and labels back to automatic", "None", "Plotting") });

parsers->insert({ "reset_yticks", mvPythonParser({
{mvPythonDataType::String, "plot"},
}, "Sets plots y ticks and labels back to automatic", "None", "Plotting") });
}

static void AddLogCommands(std::map<std::string, mvPythonParser>* parsers)
Expand Down
15 changes: 8 additions & 7 deletions DearPyGui/include/mvPythonTranslator.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,14 @@ namespace Marvel {
static mvVec2 ToVec2 (PyObject* value, const std::string& message = "Type must be a list or tuple of floats.");
static std::string ToString(PyObject* value, const std::string& message = "Type must be a string.");

static std::vector<mvVec2> ToVectVec2 (PyObject* value, const std::string& message = "Type must be a list/tuple of list/tuple.");
static std::vector<int> ToIntVect (PyObject* value, const std::string& message = "Type must be a list or tuple of integers.");
static std::vector<float> ToFloatVect (PyObject* value, const std::string& message = "Type must be a list or tuple of floats.");
static std::vector<std::string> ToStringVect (PyObject* value, const std::string& message = "Type must be a list or tuple of strings.");
static std::vector<std::pair<int, int>> ToVectInt2 (PyObject* value, const std::string& message = "Type must be an list/tuple of integer.");
static std::vector<std::pair<std::string, std::string>> ToVectPairString(PyObject* value, const std::string& message = "Type must be an list/tuple of string pairs.");
static std::vector<std::vector<std::string>> ToVectVectString(PyObject* value, const std::string& message = "Type must be an list/tuple of list/tuple of strings.");
static std::vector<mvVec2> ToVectVec2 (PyObject* value, const std::string& message = "Type must be a list/tuple of list/tuple.");
static std::vector<int> ToIntVect (PyObject* value, const std::string& message = "Type must be a list or tuple of integers.");
static std::vector<float> ToFloatVect (PyObject* value, const std::string& message = "Type must be a list or tuple of floats.");
static std::vector<std::string> ToStringVect (PyObject* value, const std::string& message = "Type must be a list or tuple of strings.");
static std::vector<std::pair<int, int>> ToVectInt2 (PyObject* value, const std::string& message = "Type must be an list/tuple of integer.");
static std::vector<std::pair<std::string, std::string>> ToVectPairString (PyObject* value, const std::string& message = "Type must be an list/tuple of string pairs.");
static std::vector<std::vector<std::string>> ToVectVectString (PyObject* value, const std::string& message = "Type must be an list/tuple of list/tuple of strings.");
static std::vector<std::pair<std::string, float>> ToVectPairStringFloat(PyObject* value, const std::string& message = "Type must be an list/tuple of str,float pairs.");

private:

Expand Down
50 changes: 50 additions & 0 deletions DearPyGui/src/Core/AppItems/mvPlot.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,38 @@ namespace Marvel {
m_colormap = colormap;
}

void resetXTicks()
{
m_xlabels.clear();
m_xclabels.clear();
m_xlabelLocations.clear();
}

void resetYTicks()
{
m_ylabels.clear();
m_yclabels.clear();
m_ylabelLocations.clear();
}

void setXTicks(const std::vector<std::string>& labels, const std::vector<double>& locations)
{
m_xlabels = labels;
m_xlabelLocations = locations;

for (const auto& item : m_xlabels)
m_xclabels.push_back(item.data());
}

void setYTicks(const std::vector<std::string>& labels, const std::vector<double>& locations)
{
m_ylabels = labels;
m_ylabelLocations = locations;

for (const auto& item : m_ylabels)
m_yclabels.push_back(item.data());
}

void clear()
{
for (auto& series : m_series)
Expand All @@ -97,6 +129,17 @@ namespace Marvel {
if (m_setYLimits)
ImPlot::SetNextPlotLimitsY(m_ylimits.x, m_ylimits.y, ImGuiCond_Always);

if (!m_xlabels.empty())
{
// TODO: Checks
ImPlot::SetNextPlotTicksX(m_xlabelLocations.data(), (int)m_xlabels.size(), m_xclabels.data());
}
if (!m_ylabels.empty())
{
// TODO: Checks
ImPlot::SetNextPlotTicksY(m_ylabelLocations.data(), (int)m_ylabels.size(), m_yclabels.data());
}

if (ImPlot::BeginPlot(m_name.c_str(), m_xaxisName.c_str(), m_yaxisName.c_str(),
ImVec2((float)m_width, (float)m_height), m_flags,
m_xflags, m_yflags) )
Expand Down Expand Up @@ -185,6 +228,13 @@ namespace Marvel {
std::string m_queryCallback;
bool m_queried = false;
float m_queryArea[4] = {0.0f , 0.0f, 0.0f, 0.0f};

std::vector<std::string> m_xlabels;
std::vector<std::string> m_ylabels;
std::vector<const char*> m_xclabels; // to prevent conversion from string to char* every frame
std::vector<const char*> m_yclabels; // to prevent conversion from string to char* every frame
std::vector<double> m_xlabelLocations;
std::vector<double> m_ylabelLocations;

std::vector<mvSeries*> m_series;

Expand Down
112 changes: 112 additions & 0 deletions DearPyGui/src/Core/mvMarvel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,114 @@ namespace Marvel {
return mvPythonTranslator::GetPyNone();
}

PyObject* reset_xticks(PyObject* self, PyObject* args, PyObject* kwargs)
{
const char* plot;

if (!(*mvApp::GetApp()->getParsers())["reset_xticks"].parse(args, kwargs, __FUNCTION__, &plot))
return mvPythonTranslator::GetPyNone();

mvAppItem* aplot = mvApp::GetApp()->getItem(plot);
if (aplot == nullptr)
{
std::string message = plot;
ThrowPythonException(message + " plot does not exist.");
return mvPythonTranslator::GetPyNone();
}
mvPlot* graph = static_cast<mvPlot*>(aplot);

graph->resetXTicks();

return mvPythonTranslator::GetPyNone();
}

PyObject* reset_yticks(PyObject* self, PyObject* args, PyObject* kwargs)
{
const char* plot;

if (!(*mvApp::GetApp()->getParsers())["reset_yticks"].parse(args, kwargs, __FUNCTION__, &plot))
return mvPythonTranslator::GetPyNone();

mvAppItem* aplot = mvApp::GetApp()->getItem(plot);
if (aplot == nullptr)
{
std::string message = plot;
ThrowPythonException(message + " plot does not exist.");
return mvPythonTranslator::GetPyNone();
}
mvPlot* graph = static_cast<mvPlot*>(aplot);

graph->resetXTicks();

return mvPythonTranslator::GetPyNone();
}

PyObject* set_xticks(PyObject* self, PyObject* args, PyObject* kwargs)
{
const char* plot;
PyObject* label_pairs;

if (!(*mvApp::GetApp()->getParsers())["set_xticks"].parse(args, kwargs, __FUNCTION__, &plot, &label_pairs))
return mvPythonTranslator::GetPyNone();

mvAppItem* aplot = mvApp::GetApp()->getItem(plot);
if (aplot == nullptr)
{
std::string message = plot;
ThrowPythonException(message + " plot does not exist.");
return mvPythonTranslator::GetPyNone();
}
mvPlot* graph = static_cast<mvPlot*>(aplot);

auto mlabel_pairs = mvPythonTranslator::ToVectPairStringFloat(label_pairs);

std::vector<std::string> labels;
std::vector<double> locations;

for (const auto& item : mlabel_pairs)
{
labels.emplace_back(item.first.c_str());
locations.emplace_back((double)item.second);
}

graph->setXTicks(labels, locations);

return mvPythonTranslator::GetPyNone();
}

PyObject* set_yticks(PyObject* self, PyObject* args, PyObject* kwargs)
{
const char* plot;
PyObject* label_pairs;

if (!(*mvApp::GetApp()->getParsers())["set_yticks"].parse(args, kwargs, __FUNCTION__, &plot, &label_pairs))
return mvPythonTranslator::GetPyNone();

mvAppItem* aplot = mvApp::GetApp()->getItem(plot);
if (aplot == nullptr)
{
std::string message = plot;
ThrowPythonException(message + " plot does not exist.");
return mvPythonTranslator::GetPyNone();
}
mvPlot* graph = static_cast<mvPlot*>(aplot);

auto mlabel_pairs = mvPythonTranslator::ToVectPairStringFloat(label_pairs);

std::vector<std::string> labels;
std::vector<double> locations;

for (const auto& item : mlabel_pairs)
{
labels.emplace_back(item.first.c_str());
locations.emplace_back((double)item.second);
}

graph->setYTicks(labels, locations);

return mvPythonTranslator::GetPyNone();
}

PyObject* set_plot_xlimits_auto(PyObject* self, PyObject* args, PyObject* kwargs)
{
const char* plot;
Expand Down Expand Up @@ -5462,6 +5570,10 @@ namespace Marvel {
ADD_PYTHON_FUNCTION(is_plot_queried)
ADD_PYTHON_FUNCTION(get_plot_query_area)
ADD_PYTHON_FUNCTION(clear_plot)
ADD_PYTHON_FUNCTION(reset_xticks)
ADD_PYTHON_FUNCTION(reset_yticks)
ADD_PYTHON_FUNCTION(set_xticks)
ADD_PYTHON_FUNCTION(set_yticks)
ADD_PYTHON_FUNCTION(set_plot_xlimits_auto)
ADD_PYTHON_FUNCTION(set_plot_ylimits_auto)
ADD_PYTHON_FUNCTION(set_plot_xlimits)
Expand Down
33 changes: 33 additions & 0 deletions DearPyGui/src/Core/mvPythonTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,4 +450,37 @@ namespace Marvel {

return results;
}

std::vector<std::pair<std::string, float>> mvPythonTranslator::ToVectPairStringFloat(PyObject* value, const std::string& message)
{
std::vector<std::pair<std::string, float>> items;
mvGlobalIntepreterLock gil;

if (PyTuple_Check(value))
{
for (size_t i = 0; i < PyTuple_Size(value); i++)
{
PyObject* item = PyTuple_GetItem(value, i);
if (PyTuple_Size(item) == 2)
items.emplace_back(PyUnicode_AsUTF8(PyTuple_GetItem(item, 0)), (float)PyFloat_AsDouble(PyTuple_GetItem(item, 1)));

}

}
else if (PyList_Check(value))
{
for (size_t i = 0; i < PyList_Size(value); i++)
{
PyObject* item = PyList_GetItem(value, i);
if (PyList_Size(item) == 2)
items.emplace_back(PyUnicode_AsUTF8(PyList_GetItem(item, 0)), (float)PyFloat_AsDouble(PyList_GetItem(item, 1)));

}
}

else
ThrowPythonException(message);

return items;
}
}
16 changes: 16 additions & 0 deletions DearPyGui/stubs/dearpygui.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,22 @@ def set_plot_xlimits(plot: str, xmin: float, xmax: float) -> None:
"""Sets x axis limits of a plot. (can be undone with set_plot_xlimits_auto()"""
...

def set_xticks(plot: str, label_pairs: List[List[str, float]]) -> None:
"""Sets plots x ticks and labels"""
...

def set_yticks(plot: str, label_pairs: List[List[str, float]]) -> None:
"""Sets plots x ticks and labels"""
...

def reset_xticks(plot: str) -> None:
"""Sets plots x ticks and labels back to automatic"""
...

def reset_yticks(plot: str) -> None:
"""Sets plots y ticks and labels back to automatic"""
...

def set_plot_xlimits_auto(plot: str) -> None:
"""Sets plots x limits to be automatic."""
...
Expand Down
2 changes: 2 additions & 0 deletions DearSandbox/Demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ def InsertCol(sender, data):
add_button("Plot data", callback="PlotCallback")
add_listbox("Colormaps", ("Default", "Dark", "Pastel", "Paired", "Viridis", "Plasma", "Hot", "Cool", "Pink", "Jet"), width=500, height=3, callback="colormapCallback")
add_plot("Plot", "x-axis", "y-axis", height=-1);
set_xticks("Plot", [["X-axis", 0], ["1", 1]])
set_yticks("Plot", [["Y-axis", 0], ["1", 1]])
end_tab()
add_tab("Simple Plots")
add_simple_plot("Simpleplot1", (0.3, 0.9, 2.5, 8.9))
Expand Down

0 comments on commit 984da54

Please sign in to comment.