Last active
August 17, 2020 01:36
-
-
Save diegopenilla/319f8555f5b5787c1494788cf460527c to your computer and use it in GitHub Desktop.
2D/3D grapher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from IPython.core.display import display, HTML, Markdown, clear_output | |
import json | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import ipywidgets as widgets | |
# Defining Widgets: | |
equation = widgets.Text( | |
value='np.sin(X*Y)+np.cos(X+Y)', | |
placeholder='Type something', | |
description='Equation:') | |
range_ = widgets.FloatRangeSlider( | |
value=[-5, 5], | |
min=-100, | |
step=0.1, | |
description='range:', | |
orientation='horizontal', | |
readout=True, | |
readout_format='d',) | |
points = widgets.IntText( | |
value=50, | |
description='Detail:') | |
# DEFINING FUNCTIONS | |
def plot2D(x_points): | |
# I find where the letter X is in my equation text and replace by placeholders {} | |
number_of_placeholders = equation.value.count('X') | |
decomposed_equation = equation.value.replace('X', '{}') | |
y = [] | |
for point in x_points: | |
dicti = {i: point for i in range(number_of_placeholders)} | |
decomposed_eq = decomposed_equation.format(*dicti.values()) | |
# WARNING: couldn't figure out any other way, let me know if you know | |
exec("""global res | |
res = {}""".format(decomposed_eq)) | |
y.append(res) | |
plt.plot(x_points, y) | |
plt.show() | |
def plot3D(X, Y, Z): | |
options = { | |
"width": "100%", | |
"style": "surface", | |
"showPerspective": True, | |
"showGrid": True, | |
"showShadow": True, | |
"keepAspectRatio": False, | |
"height": "600px"} | |
# LOADING DATA | |
data = [ {"x": X[y,x], | |
"y": Y[y,x], | |
"z": Z[y,x]} for y in range(Y.shape[0]) for x in range(Y.shape[1]) ] | |
visual_code = r""" | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.css" type="text/css" rel="stylesheet" /> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script> | |
<div id="pos" style="top:0px;left:0px;position:absolute;"></div> | |
<div id="visualization"></div> | |
<script type="text/javascript"> | |
var data = new vis.DataSet(); | |
data.add(""" + json.dumps(data) + """); | |
var options = """ + json.dumps(options) + """; | |
var container = document.getElementById("visualization"); | |
var graph3d = new vis.Graph3d(container, data, options); | |
// setting the camera position initial | |
graph3d.setCameraPosition({horizontal:0.8197963, vertical:0.945, distance:1.988}) | |
graph3d.on("cameraPositionChange", function(evt) | |
{ | |
elem = document.getElementById("pos"); | |
elem.innerHTML = "Horizontal: " + evt.horizontal + "<br>Vertical: " + evt.vertical + "<br>Camera Distance: " + evt.distance; | |
}); | |
</script> | |
""" | |
html= "<iframe srcdoc='"+visual_code+"' width='75%' height='600px' style='border:10;' scrolling='no'> </iframe>" | |
display(HTML(html)) | |
# CREATING BUTTON | |
# if X and Y are inside equation.value we run plot3D | |
# otherwise we run plot2D | |
button = widgets.Button(description='Reveal Equation') | |
out = widgets.Output() | |
def on_button_clicked(b): | |
global X, Y | |
with out: | |
clear_output() | |
# computing the x points to evaluate our function | |
x_points = np.linspace(range_.value[0], | |
range_.value[1], points.value) | |
X, Y = np.meshgrid(x_points, x_points) | |
# WARNING: couldn't figure out any other way, let me know if you know | |
exec("""global Z | |
Z = {} | |
""".format(equation.value)) | |
if 'Y' in equation.value and 'X' in equation.value: | |
plot3D(X,Y,Z) | |
elif 'Y' in equation.value: | |
equation.value = equation.value.replace('Y', 'X') | |
plot2D(x_points) | |
else: | |
plot2D(x_points) | |
button.on_click(on_button_clicked) | |
info = Markdown("""# 2D/3D Grapher | |
- Write down the equation you want to plot in the Equation window. | |
- If only $X$ or $Y$ is defined in the equation a 2D plot will be shown. | |
- If $Y$ and $X$ are defined a 3D plot will be shown. | |
- Detail specifies the number of points created between the specified range.""") | |
grapher = widgets.VBox([points, range_, equation, button, out]) | |
display(info, grapher) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment