def stream_plot(): x = np.linspace(-3, 3, 200) y = np.linspace(-3, 3, 200) X, Y = np.meshgrid(x, y) dy = X**2 - Y**2 dx = np.log((Y**2 - Y + 1) / 3) figure = ff.create_streamline(x, y, dx, dy, arrow_scale=.2, density=1.5, name="Лінії потоку") figure.add_trace( go.Scatter(x=[2, -0.2], y=[2, 1], mode='lines+markers', line=dict(color='green', width=3))) figure.add_trace( go.Scatter(x=[2, 1.4], y=[2, 1], mode='lines+markers', line=dict(color='green', width=3))) figure.update_layout( title=r"$\text{Лінії потоку системи диференційних рівнянь}$", font=dict(family="Arial", size=20, color="black")) figure['layout'].update(width=500, height=500, autosize=False) figure.show()
def make_Streamlines(surfsens, density='auto', arrow_scale=0.1, sensorsources=None, color=None, **kwargs): ''' sensorsources: iterable of magpylib sources in order to make the streamlines plot the Bfield values need to be retrieved for the corresponding sources ''' if sensorsources is None: sensorsources = [] angle = surfsens.angle pos = surfsens.position axis = surfsens.axis density = surfsens.Nelem[0] / 4 if density == 'auto' else density B = surfsens.getBarray(*sensorsources).reshape(*surfsens.Nelem, 3) surfsens.position = np.array([0, 0, 0]) surfsens.angle = 0 x, y, z = surfsens.positions.T.reshape(3, *surfsens.Nelem) xs, ys = x[:, 0], y.T[:, 0] surfsens.angle = angle surfsens.position = pos surfsens.axis = axis Bx, By = B[:, :, 0], B[:, :, 1] streamline = create_streamline(x=xs, y=ys, u=Bx.T, v=By.T, arrow_scale=arrow_scale, density=density) sl = streamline.data[0] points = np.array([sl.x, sl.y, np.zeros(len(sl.x))]) if angle != 0: x, y, z = np.array([ angleAxisRotation(p, angle, axis, anchor=[0, 0, 0]) for p in points.T ]).T else: x, y, z = points trace = go.Scatter3d(x=repnan(x) + pos[0], y=repnan(y) + pos[1], z=repnan(z) + pos[2], mode='lines', name=f'streamlines ({len(sensorsources)} sources)') trace.update(**kwargs) return trace
def to_plot(): x_source, y_source = 0.0, 0.0 x = np.linspace(-5, 5, 500) y = np.linspace(-5, 5, 500) X, Y = np.meshgrid(x, y) dx = 1 * X - 1 * Y - 5 dy = 2 * X + 1 * Y figure = ff.create_streamline(x, y, dx, dy, arrow_scale=.2, density=1.5, name="Лінії потоку") figure.add_trace( go.Scatter(x=[0, -0.7], y=[0, -0.44], mode='lines+markers', name="Перший власний вектор", line=dict(color='green', width=3))) figure.add_trace( go.Scatter(x=[0, 0.7], y=[0, -0.9], mode='lines+markers', name="Другий власний вектор", line=dict(color='green', width=3))) figure.add_trace( go.Scatter(x=[-1, 2], y=[0, -0.5], text=[ r"$\overline{V} \text{ (λ=3) }$", r"$\overline{U} \text{ (λ=6) }$" ], mode="text", name="Власні вектори")) figure.update_layout(title=r"dsadasd", font=dict(family="Arial", size=18, color="black")) figure.update_xaxes(range=[-5, 5]) figure.update_yaxes(range=[-5, 5]) figure['layout'].update(width=700, height=600, autosize=False) figure.show()
def plot_stream_lines(self): # Prepare the mesh and vx,vy velocity values for the streamlines plot function. nodes = self.msh.M * self.msh.N # Rearrange the nodes x,y coords in a single array, and flatten the vx,vy velocities. the_points = np.zeros((nodes, 2)) the_vx_values = np.zeros((nodes,)) the_vy_values = np.zeros((nodes,)) i = 0 for row in range(self.msh.M): for col in range(self.msh.N): the_points[i,0] = self.msh.the_nodes_x_coords[row,col] the_points[i,1] = self.msh.the_nodes_y_coords[row,col] the_vx_values[i] = self.fields.vx[row,col] the_vy_values[i] = self.fields.vy[row,col] i = i + 1 x_ = np.linspace(self.msh.x0, self.msh.xf, 1000) y_ = np.linspace(self.msh.y0, self.msh.yf, 1000) x, y = np.meshgrid(x_, y_) VX = griddata(the_points, the_vx_values, (x, y), method='cubic') VY = griddata(the_points, the_vy_values, (x, y), method='cubic') # Last step, the original solid nodes, should remain solid in the mapped VX,VY velocities # for the streamlines plot. FLUID_NODES = self.map_fluid_nodes(self.msh, x, y) VX = VX * FLUID_NODES VY = VY * FLUID_NODES fig = ff.create_streamline(x_,y_, VX, VY, arrow_scale=.1, density=2,name='Streamlines') theta = np.linspace(0, 2 * np.pi, 100) fig.add_scatter(x=self.msh.cylinder_R*np.cos(theta),y=self.msh.cylinder_R*np.sin(theta), fill='toself', fillcolor='violet', line_color='violet', name='Cylinder') fig.layout.update({'title': 'Streamlines'}, font={'size':28}) fig.show() pio.write_image(fig, files_output_path + self.output_files_name + 'Streamlines.png', width=2864, height=1356)
def create_streamline(*args, **kwargs): FigureFactory._deprecated('create_streamline') from plotly.figure_factory import create_streamline return create_streamline(*args, **kwargs)
def StreamPlot(k,inf_rate,epsilon,sigma): #NOT WORKING !!!!! # 1) Find system solutions def dRho_dt(Rho, t=0): den_w = (epsilon*(Rho[0])**sigma + (1-epsilon)*(Rho[1])**sigma) w1 = (epsilon*Rho[0]**sigma)/den_w w2 = ((1-epsilon)*Rho[1]**sigma)/den_w # Rho = [rho1,rho2] return np.array([Rho[0]*(inf_rate*k*w1*(1-Rho[0]) - 1), Rho[1]*(inf_rate*k*w2*(1-Rho[1]) - 1)]) RESULTS = [] z = 0 one_solution = False x_total = 10 y_total = 10 x0 = np.linspace(0,1,x_total) y0 = np.linspace(0,1,y_total) for r1 in range(10): for r2 in range(10): guess = [x0[r1],y0[r2]] sol,info,ier,mesg = optimize.fsolve(dRho_dt, guess, xtol = 1e-6,full_output = True) sol_l = list(sol) if (ier == 1): if (not one_solution): one_solution = True RESULTS.append(sol_l) else: solution_found = False for j in RESULTS: solution_found = (abs(j[0]-sol_l[0]) <= 0.001) and (abs(j[1]-sol_l[1]) <= 0.001) if(not solution_found): RESULTS.append(sol_l) z += 1 else: continue # 2) Draw Streamplot N = 50 rho1_start, rho1_end = 0.01, 1.0 rho2_start, rho2_end = 0.01, 1.0 rho1 = np.linspace(rho1_start, rho1_end, N) rho2 = np.linspace(rho2_start, rho2_end, N) RHO1, RHO2 = np.meshgrid(rho1, rho2) den_w = (epsilon*(RHO1)**sigma + (1-epsilon)*(RHO2)**sigma) w1 = (epsilon*RHO1**sigma)/den_w w2 = ((1-epsilon)*RHO2**sigma)/den_w #Rho = [rho1,rho2] U = RHO1*(inf_rate*k*w1*(1-RHO1) - 1) V = RHO2*(inf_rate*k*w2*(1-RHO2) - 1) rho_on_axis = (inf_rate*k - 1)/(inf_rate*k) # Add source point rho1_axis = go.Scatter(x=[rho_on_axis], y=[0], mode='markers', marker=go.Marker(size=14,symbol='diamond',color='red')) rho2_axis = go.Scatter(x=[0], y=[rho_on_axis], mode='markers', marker=go.Marker(size=14,symbol='diamond',color='red')) fig = ff.create_streamline(rho1, rho2, U, V, density=1.2, arrow_scale=.01) # Add source point to figure fig['data'].append(rho1_axis) fig['data'].append(rho2_axis) for res in RESULTS: fixed_point = go.Scatter(x=[res[0]], y=[res[1]], mode='markers', marker=go.Marker(size=14,symbol='circle',color='red')) fig['data'].append(fixed_point) # Image returned in html and open in browser pyoff.plot(fig, filename='Streamline.html')
def _update_interactive(self, params): for i, s in enumerate(self.series): if s.is_interactive: self.series[i].update_data(params) if s.is_2Dline and s.is_parametric: x, y, param = self.series[i].get_data() self.fig.data[i]["x"] = x self.fig.data[i]["y"] = y self.fig.data[i]["marker"]["color"] = param self.fig.data[i]["customdata"] = param elif s.is_2Dline: x, y = self.series[i].get_data() x, y, _ = self._detect_poles(x, y) if s.is_geometry: self.fig.data[i]["x"] = x self.fig.data[i]["y"] = y elif s.is_3Dline: x, y, z, param = s.get_data() self.fig.data[i]["x"] = x self.fig.data[i]["y"] = y self.fig.data[i]["z"] = z self.fig.data[i]["line"]["color"] = param elif s.is_3Dsurface and s.is_parametric: x, y, z = self.series[i].get_data() self.fig.data[i]["x"] = x self.fig.data[i]["y"] = y self.fig.data[i]["z"] = z elif (s.is_3Dsurface and (not s.is_complex)) or (s.is_3Dsurface and s.is_complex and (s.real or s.imag)): x, y, z = self.series[i].get_data() self.fig.data[i]["z"] = z elif s.is_contour and (not s.is_complex): _, _, zz = s.get_data() self.fig.data[i]["z"] = zz elif s.is_implicit: points = s.get_data() if len(points) == 2: raise NotImplementedError else: _, _, zz, ones, _ = points self.fig.data[i]["z"] = ones elif s.is_vector and s.is_3D: streamlines = self._kwargs.get("streamlines", False) if streamlines: raise NotImplementedError _, _, _, u, v, w = self.series[i].get_data() self.fig.data[i]["u"] = u.flatten() self.fig.data[i]["v"] = v.flatten() self.fig.data[i]["w"] = w.flatten() elif s.is_vector: x, y, u, v = self.series[i].get_data() streamlines = self._kwargs.get("streamlines", False) if streamlines: streams = create_streamline(x[0, :], y[:, 0], u, v) data = streams.data[0] # TODO: iplot doesn't work with 2D streamlines. Why? # Is it possible that the sequential update of x and y # is the cause of the error? Since at every update, # len(x) = len(y) but those are different from before. raise NotImplementedError else: # default values qkw = dict(line_color=self.quivers_colors[i], scale=0.075, name=s.label) # user-provided values quiver_kw = self._kwargs.get("quiver_kw", dict()) quivers = create_quiver(x, y, u, v, **merge({}, qkw, quiver_kw)) data = quivers.data[0] self.fig.data[i]["x"] = data["x"] self.fig.data[i]["y"] = data["y"] elif s.is_complex: if s.is_domain_coloring: raise NotImplementedError # TODO: for some unkown reason, domain_coloring and # interactive plot don't like each other... # x, y, z, magn_angle, img, discr, colors = self._get_image(s) # self.fig.data[i]["z"] = img # self.fig.data[i]["x0"] = -4 # self.fig.data[i]["y0"] = -5 # # self.fig.data[i]["customdata"] = magn_angle else: xx, yy, mag_angle, colors, colorscale = s.get_data() mag, angle = mag_angle[:, :, 0], mag_angle[:, :, 1] self.fig.data[i]["z"] = mag self.fig.data[i]["surfacecolor"] = angle self.fig.data[i]["customdata"] = angle m, M = min(angle.flatten()), max(angle.flatten()) # show pi symbols on the colorbar if the range is close # enough to [-pi, pi] if (abs(m + self.pi) < 1e-02) and (abs(M - self.pi) < 1e-02): self.fig.data[i]["colorbar"]["tickvals"] = [ m, -self.pi / 2, 0, self.pi / 2, M, ] self.fig.data[i]["colorbar"]["ticktext"] = [ "-π", "-π / 2", "0", "π / 2", "π", ] elif s.is_geometry and not (s.is_2Dline): x, y = self.series[i].get_data() self.fig.data[i]["x"] = x self.fig.data[i]["y"] = y
def _process_series(self, series): self._init_cyclers() # if legend=True and both 3d lines and surfaces are shown, then hide the # surfaces color bars and only shows line labels in the legend. # TODO: can I show both colorbars and legends by scaling down the color # bars? show_3D_colorscales = True show_2D_vectors = False for s in series: if s.is_3Dline: show_3D_colorscales = False if s.is_2Dvector: show_2D_vectors = True self._fig.data = [] count = 0 for ii, s in enumerate(series): if s.is_2Dline: line_kw = self._kwargs.get("line_kw", dict()) if s.is_parametric: x, y, param = s.get_data() # hides/show the colormap depending on self._use_cm mode = "lines+markers" if not s.is_point else "markers" if (not s.is_point) and (not self._use_cm): mode = "lines" lkw = dict( name=s.label, line_color=next(self._cl), mode=mode, marker=dict( color=param, colorscale=(next( self._cyccm) if self._use_cyclic_cm( param, s.is_complex) else next(self._cm)), size=6, showscale=self.legend and self._use_cm, colorbar=self._create_colorbar(ii, s.label, True), ), customdata=param, hovertemplate=( "x: %{x}<br />y: %{y}<br />u: %{customdata}" if not s.is_complex else "x: %{x}<br />y: %{y}<br />Arg: %{customdata}"), ) self._fig.add_trace( go.Scatter(x=x, y=y, **merge({}, lkw, line_kw))) else: x, y = s.get_data() x, y, _ = self._detect_poles(x, y) lkw = dict( name=s.label, mode="lines" if not s.is_point else "markers", line_color=next(self._cl), ) self._fig.add_trace( go.Scatter(x=x, y=y, **merge({}, lkw, line_kw))) elif s.is_3Dline: # NOTE: As a design choice, I decided to show the legend entry # as well as the colorbar (if use_cm=True). Even though the # legend entry shows the wrong color (black line), it is useful # in order to hide/show a specific series whenever we are # plotting multiple series. x, y, z, param = s.get_data() if not s.is_point: lkw = dict( name=s.label, mode="lines", line=dict( width=4, colorscale=(next(self._cm) if self._use_cm else self._solid_colorscale()), color=param, showscale=self.legend and self._use_cm, colorbar=self._create_colorbar(ii, s.label, True), ), ) else: lkw = dict(name=s.label, mode="markers", line_color=next(self._cl)) line_kw = self._kwargs.get("line_kw", dict()) self._fig.add_trace( go.Scatter3d(x=x, y=y, z=z, **merge({}, lkw, line_kw))) elif (s.is_3Dsurface and (not s.is_complex)) or (s.is_3Dsurface and s.is_complex and (s.real or s.imag)): xx, yy, zz = s.get_data() # create a solid color to be used when self._use_cm=False col = next(self._cl) colorscale = [[0, col], [1, col]] colormap = next(self._cm) skw = dict( name=s.label, showscale=self.legend and show_3D_colorscales, colorbar=self._create_colorbar(ii, s.label), colorscale=colormap if self._use_cm else colorscale, ) surface_kw = self._kwargs.get("surface_kw", dict()) self._fig.add_trace( go.Surface(x=xx, y=yy, z=zz, **merge({}, skw, surface_kw))) # TODO: remove this? Making it works with iplot is difficult if self._kwargs.get("wireframe", False): line_marker = dict(color=next(self._wfcm), width=2) for i, j, k in zip(xx, yy, zz): self._fig.add_trace( go.Scatter3d( x=i, y=j, z=k, mode="lines", line=line_marker, showlegend=False, )) for i, j, k in zip(xx.T, yy.T, zz.T): self._fig.add_trace( go.Scatter3d( x=i, y=j, z=k, mode="lines", line=line_marker, showlegend=False, )) count += 1 elif s.is_contour and (not s.is_complex): xx, yy, zz = s.get_data() xx = xx[0, :] yy = yy[:, 0] # default values ckw = dict( contours=dict( coloring=None, showlabels=False, ), colorscale=next(self._cm), colorbar=self._create_colorbar(ii, s.label, show_2D_vectors), ) # user-provided values contour_kw = self._kwargs.get("contour_kw", dict()) self._fig.add_trace( go.Contour(x=xx, y=yy, z=zz, **merge({}, ckw, contour_kw))) count += 1 elif s.is_implicit: points = s.get_data() if len(points) == 2: # interval math plotting x, y, pixels = self._get_pixels(s, points[0]) ckw = dict( colorscale=[ [0, "rgba(0,0,0,0)"], [1, next(self._cl)], ], showscale=False, name=s.label, ) contour_kw = self._kwargs.get("contour_kw", dict()) self._fig.add_trace( go.Heatmap(x=x, y=y, z=pixels, **merge({}, ckw, contour_kw))) else: x, y, z, ones, plot_type = points zf = z.flatten() m, M = min(zf), max(zf) col = next(self._cl) # default values ckw = dict( contours=dict( coloring="none" if plot_type == "contour" else None, showlabels=False, type="levels" if plot_type == "contour" else "constraint", operation="<", value=[(m + M) / 2], ), colorscale=[ [0, "rgba(0,0,0,0)"], [1, next(self._cl)], ], fillcolor=col, showscale=True, name=s.label, line=dict(color=col), ) contour_kw = self._kwargs.get("contour_kw", dict()) # TODO: sadly, Plotly does not support yet setting contour # levels, hence the visualization will look ugly whenever # plot_type="contour". # https://github.com/plotly/plotly.js/issues/4503 self._fig.add_trace( go.Contour(x=x, y=y, z=ones, **merge({}, ckw, contour_kw))) count += 1 elif s.is_vector: if s.is_2Dvector: xx, yy, uu, vv = s.get_data() streamlines = self._kwargs.get("streamlines", False) if streamlines: # NOTE: currently, it is not possible to create streamlines with # a color scale: https://community.plotly.com/t/how-to-make-python-quiver-with-colorscale/41028 # default values skw = dict(line_color=next(self._qc), arrow_scale=0.15, name=s.label) # user-provided values stream_kw = self._kwargs.get("stream_kw", dict()) stream = create_streamline(xx[0, :], yy[:, 0], uu, vv, **merge({}, skw, stream_kw)) self._fig.add_trace(stream.data[0]) else: # NOTE: currently, it is not possible to create quivers with # a color scale: https://community.plotly.com/t/how-to-make-python-quiver-with-colorscale/41028 # default values qkw = dict(line_color=next(self._qc), scale=0.075, name=s.label) # user-provided values quiver_kw = self._kwargs.get("quiver_kw", dict()) quiver = create_quiver( xx, yy, uu, vv, **merge({}, qkw, quiver_kw)) # merge two dictionaries self._fig.add_trace(quiver.data[0]) else: xx, yy, zz, uu, vv, ww = s.get_data() streamlines = self._kwargs.get("streamlines", False) if streamlines: seeds_points = get_seeds_points(xx, yy, zz, uu, vv, ww) # default values skw = dict( colorscale=next(self._cm), sizeref=0.3, colorbar=self._create_colorbar(ii, s.label), starts=dict( x=seeds_points[:, 0], y=seeds_points[:, 1], z=seeds_points[:, 2], ), ) # user-provided values stream_kw = self._kwargs.get("stream_kw", dict()) self._fig.add_trace( go.Streamtube(x=xx.flatten(), y=yy.flatten(), z=zz.flatten(), u=uu.flatten(), v=vv.flatten(), w=ww.flatten(), **merge({}, skw, stream_kw))) else: # default values qkw = dict( showscale=(not s.is_slice) or self.legend, colorscale=next(self._cm), sizemode="absolute", sizeref=40, colorbar=self._create_colorbar(ii, s.label), ) # user-provided values quiver_kw = self._kwargs.get("quiver_kw", dict()) self._fig.add_trace( go.Cone(x=xx.flatten(), y=yy.flatten(), z=zz.flatten(), u=uu.flatten(), v=vv.flatten(), w=ww.flatten(), **merge({}, qkw, quiver_kw))) count += 1 elif s.is_complex: if s.is_domain_coloring: x, y, magn_angle, img, colors = s.get_data() xmin, xmax = x.min(), x.max() ymin, ymax = y.min(), y.max() self._fig.add_trace( go.Image( x0=xmin, y0=ymin, dx=(xmax - xmin) / s.n1, dy=(ymax - ymin) / s.n2, z=img, name=s.label, customdata=magn_angle, hovertemplate= ("x: %{x}<br />y: %{y}<br />RGB: %{z}" + "<br />Abs: %{customdata[0]}<br />Arg: %{customdata[1]}" ), )) if colors is not None: # chroma/phase-colorbar self._fig.add_trace( go.Scatter( x=[xmin, xmax], y=[ymin, ymax], showlegend=False, mode="markers", marker=dict( opacity=0, colorscale=[ "rgb(%s, %s, %s)" % tuple(c) for c in colors ], color=[-self.pi, self.pi], colorbar=dict( tickvals=[ -self.pi, -self.pi / 2, 0, self.pi / 2, self.pi, ], ticktext=[ "-π", "-π / 2", "0", "π / 2", "π", ], x=1 + 0.1 * count, title="Argument", titleside="right", ), showscale=True, ), )) if s.coloring == "f": # lightness/magnitude-colorbar self._fig.add_trace( go.Scatter( x=[xmin, xmax], y=[ymin, ymax], showlegend=False, mode="markers", marker=dict( opacity=0, colorscale=[[0, "black"], [1, "white"]], color=[0, 1e20], colorbar=dict( tickvals=[0, 1e20], ticktext=["0", "∞"], x=1 + 0.1 * (count + 1), title="Magnitude", titleside="right", ), showscale=True, ), )) count += 2 else: xx, yy, mag_angle, colors, colorscale = s.get_data() mag, angle = mag_angle[:, :, 0], mag_angle[:, :, 1] if s.coloring != "a": warnings.warn( "Plotly doesn't support custom coloring " + "over surfaces. The surface color will show the " + "argument of the complex function.") # create a solid color to be used when self._use_cm=False col = next(self._cl) colorscale = [[0, col], [1, col]] colormap = next(self._cm) if not s.is_complex else next( self._cyccm) skw = dict( name=s.label, showscale=self.legend and show_3D_colorscales, colorbar=dict( x=1 + 0.1 * count, title=s.label, titleside="right", ), colorscale=colormap if self._use_cm else colorscale, surfacecolor=angle, customdata=angle, hovertemplate= "x: %{x}<br />y: %{y}<br />Abs: %{z}<br />Arg: %{customdata}", ) m, M = min(angle.flatten()), max(angle.flatten()) # show pi symbols on the colorbar if the range is close # enough to [-pi, pi] if (abs(m + self.pi) < 1e-02) and (abs(M - self.pi) < 1e-02): skw["colorbar"]["tickvals"] = [ m, -self.pi / 2, 0, self.pi / 2, M, ] skw["colorbar"]["ticktext"] = [ "-π", "-π / 2", "0", "π / 2", "π", ] surface_kw = self._kwargs.get("surface_kw", dict()) self._fig.add_trace( go.Surface(x=xx, y=yy, z=mag, **merge({}, skw, surface_kw))) count += 1 elif s.is_geometry: x, y = s.get_data() lkw = dict(name=s.label, mode="lines", fill="toself", line_color=next(self._cl)) line_kw = self._kwargs.get("line_kw", dict()) self._fig.add_trace( go.Scatter(x=x, y=y, **merge({}, lkw, line_kw))) else: raise NotImplementedError("{} is not supported by {}".format( type(s), type(self).__name__))
def display_graph(n_clicks, alpha, height, streamline_density, operating_checklist, *kulfan_inputs): ### Figure out if a button was pressed global n_clicks_last if n_clicks is None: n_clicks = 0 analyze_button_pressed = n_clicks > n_clicks_last n_clicks_last = n_clicks ### Parse the checklist ground_effect = "ground_effect" in operating_checklist ### Start constructing the figure airfoil = asb.Airfoil(coordinates=asb.get_kulfan_coordinates( lower_weights=np.array(kulfan_inputs[n_kulfan_inputs_per_side:]), upper_weights=np.array(kulfan_inputs[:n_kulfan_inputs_per_side]), TE_thickness=0, enforce_continuous_LE_radius=False, n_points_per_side=200, )) ### Do coordinates output coordinates_output = "\n".join( ["```"] + ["AeroSandbox Airfoil"] + ["\t%f\t%f" % tuple(coordinate) for coordinate in airfoil.coordinates] + ["```"]) ### Continue doing the airfoil things airfoil = airfoil.rotate(angle=-np.radians(alpha)) airfoil = airfoil.translate(0, height + 0.5 * np.sind(alpha)) fig = go.Figure() fig.add_trace( go.Scatter( x=airfoil.x(), y=airfoil.y(), mode="lines", name="Airfoil", fill="toself", line=dict(color="blue"), )) ### Default text output text_output = 'Click "Analyze" to compute aerodynamics!' xrng = (-0.5, 1.5) yrng = (-0.6, 0.6) if not ground_effect else (0, 1.2) if analyze_button_pressed: analysis = asb.AirfoilInviscid( airfoil=airfoil.repanel(50), op_point=asb.OperatingPoint( velocity=1, alpha=0, ), ground_effect=ground_effect, ) x = np.linspace(*xrng, 100) y = np.linspace(*yrng, 100) X, Y = np.meshgrid(x, y) u, v = analysis.calculate_velocity(x_field=X.flatten(), y_field=Y.flatten()) U = u.reshape(X.shape) V = v.reshape(Y.shape) streamline_fig = ff.create_streamline( x, y, U, V, arrow_scale=1e-16, density=streamline_density, line=dict(color="#ff82a3"), name="Streamlines", ) fig = go.Figure(data=streamline_fig.data + fig.data) text_output = make_table( pd.DataFrame({ "Engineering Quantity": ["C_L"], "Value": [f"{analysis.Cl:.3f}"] })) fig.update_layout( xaxis_title="x/c", yaxis_title="y/c", showlegend=False, yaxis=dict(scaleanchor="x", scaleratio=1), margin={"t": 0}, title=None, ) fig.update_xaxes(range=xrng) fig.update_yaxes(range=yrng) return fig, text_output, [coordinates_output]
x,y = np.meshgrid(np.arange(0, 2, .2), np.arange(0, 2, .2)) u = -np.cos(y)*x v = np.sin(x)*y+1 fig = ff.create_quiver(x, y, u, v) plot(fig) "Lignes de flux" x = np.linspace(-4, 4, 80) y = np.linspace(-4, 4, 80) Y, X = np.meshgrid(x, y) u = -(1 + X )**2 + 2*Y v = 1 - X + (Y+1)**2 fig = ff.create_streamline(x, y, u, v, arrow_scale=.2) plot(fig) "Création d'un tableau" # avec latex à la main data_matrix = [['Forme factorisée', 'Forme developpée'], ['$(a+b)^{2}$', '$a^{2}+2ab+b^{2}$'], ['$(a-b)^{2}$', '$a^{2}-2ab+b^{2}$'], ['$(a+b)(a-b)$', '$a^{2}-b^{2}$']] fig = ff.create_table(data_matrix) plot(fig, include_mathjax='cdn') # à partir d'un dataframe pandas