I'm trying to animate 2D vector with gnuplot. I want to show one line i.e, one vector at a time.
My Data Structure is as follows: They x,y,u,v
2.24448 0.270645 1.00 1.00
3.24448 0.270645 0.500 1.20
I'm able to create a static plot sing following command:
plot "datam.dat" using 1:2:3:4 with vectors filled head lw 3
Here is the output:
Here is my question: I would like to animate and show one row (i.e,) one vector at a time, how to accomplish this in GNU plot using GIF?
Thanks
Animated GIFs are created with set terminal gif animate. Check help gif for details.
Below is a simple example (tested with gnuplot 5.2). You have to make a new plot for each frame. So, put your plot command into a do for-loop. With every ::i::i you are plotting only the ith line (check help every). If you don't know the total number of lines of your datafile, do stats "YourFile.dat" and the variable STATS_records will tell you this number.
Code:
### animated graph with vectors
reset session
set term gif size 300,300 animate delay 12 loop 0 optimize
set output "AnimateVectors.gif"
# create some dummy data
set angle degrees
N = 60
set samples N
set table $Data
plot [0:360] '+' u (cos($1)):(sin($1)):(sin($1)):(cos($1)) w table
unset table
set xrange[-2.5:2.5]
set yrange[-2.5:2.5]
do for [i=0:N-1] {
plot $Data u 1:2:3:4 every ::i::i w vectors lw 2 lc rgb "red" notitle
}
set output
### end of code
Result:
Addition:
This would be the non-animated version, e.g. in a wxt-terminal.
Code:
### non-animated graph with vectors
reset session
set term wxt size 400,400
# create some dummy data
set angle degrees
N = 60
set samples N
set table $Data
plot [0:360] '+' u (cos($1)):(sin($1)):(sin($1)):(cos($1)) w table
unset table
set xrange[-2.5:2.5]
set yrange[-2.5:2.5]
plot $Data u 1:2:3:4 w vectors lw 1.5 lc rgb "red" notitle
### end of code
Result:
Addition2:
Do you maybe mean something like this? A "semi"-animated arrow? By the way, as you can see the arrow look quite different in gif and wxt terminal.
Code:
### "semi"-animated graph with vectors
reset session
set term gif size 300,300 animate delay 12 loop 0 optimize
set output "AnimateVectorsSemi.gif"
# create some dummy data
set angle degrees
N = 60
set samples N
set table $Data
plot [0:360] '+' u (cos($1)):(sin($1)):(sin($1)):(cos($1)) w table
unset table
set xrange[-2.5:2.5]
set yrange[-2.5:2.5]
do for [i=0:N-1] {
plot $Data u 1:2:3:4 every ::0::i w vectors lw 1.5 lc rgb "red" notitle
}
set output
### end of code
Result:
Related
I am trying to create a corner plot for an upcoming paper, but I'm running into difficulty. I am creating an N x N array of subplots (currently, N = 6) and then deleting a bit over half of them. The issue is that the figure doesn't seem to resize itself after I delete the extraneous subplots, so when I later add a legend using a dummy subplot, it exists in the area where a full row and column of deleted subplots were, thus enlarging the figure. I've been working on this for several hours now and haven't found a solution. Here is the MWE:
import matplotlib.pyplot as plt
%matplotlib notebook
n_char = 8
# Set up the main figure.
fig, ax = plt.subplots(n_char, n_char, figsize=(n_char, n_char))
# Get rid of the axis labels unless it's on the left-most column or bottom-most row.
for i in range(0, n_char):
# For each row, loop over each column.
for j in range(0, n_char):
# If the plot isn't in the bottom-most row, get rid of the x-axis tick labels.
if i != n_char - 1:
ax[i, j].set_xticklabels([])
# If the plot isn't in the left-most column, get rid of the y-axis tick labels.
if j != 0:
ax[i, j].set_yticklabels([])
# Remove the plots that are repetitive or boring (plotting against the same characteristic).
for i in range(0, n_char):
# For each row, loop over each column.
for j in range(0, n_char):
# Delete the offending axes.
if j >= i:
ax[i, j].remove()
# Set the spacing between the plots to a much smaller value.
fig.subplots_adjust(hspace=0.00, wspace=0.00)
# Create a big plot for the legend. Have the frame hidden.
fig.add_subplot(111, frameon=False, xticks=[], yticks=[], xticklabels=[], yticklabels=[])
# Create some dummy data to serve as the source of the legend.
plt.scatter([10], [10], color="k", s=5, zorder=2, label="Targets")
# Set the x-axis limits such that the dummy data point is invisible.
fig.gca().set_xlim(-1, 1)
# Add the legend to the plot. Have it located in the upper right.
plt.legend(scatterpoints=1, loc="upper right", fontsize=5)
# Save the final plot.
fig.savefig("./../Code Output/Other Plots/Corner_Plot_Test.png", bbox_inches="tight", dpi=500)
I have looked at many different questions here on Stack Overflow. The two most promising candidates was this one, but I found the solution wasn't quite workable due to the large number of plots (and, to be frank, I didn't fully understand the solution). I thought that the first answer in this one might also work, as I thought it was a sizing issue (i.e. the figure wasn't resizing, so creating a new subplot was creating one the size of the original figure), but all it did was resize the entire figure, so that didn't work either.
To help, I will also include an image. I took the output of the code above and edited it to show what I want:
I should add that if I don't add a subplot, the output is as I expected (i.e. it's the proper size), so the issue comes in when adding the subplot, i.e. the line fig.add_subplot(111, frameon=False, xticks=[], yticks=[], xticklabels=[], yticklabels=[]).
The use of GridSpec may help.
GridSpec is used to specify array of axes to plot. You can set widths for columns and heights for rows as ratios in the option. The unneeded row should have very small height ratio, while unneeded column very small width ratio.
Here is the runnable code and output plot:-
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
#import numpy as np
fig = plt.figure(figsize=(8, 8))
nn = 6
# will create gridspec of 6 rows, 6 columns
# 1st row will occupy v small heights
# last column will occupy v small widths
sm = 0.01 # the v small width/height
wh = (1.-sm)/(nn-1.) # useful width/height
gs = gridspec.GridSpec(nn, nn, width_ratios=[*[wh]*(nn-1), sm], \
height_ratios= [sm, *[wh]*(nn-1)])
cols, rows = nn, nn
ax = [[0 for i in range(cols)] for j in range(rows)]
for ea in range(nn):
for eb in range(nn):
ax[ea][eb] = fig.add_subplot(gs[ea, eb])
ax[ea][eb].set_xticklabels([])
ax[ea][eb].set_yticklabels([])
if eb>=ea:
ax[ea][eb].remove()
# plot data on some axes
# note that axes on the first row (index=0) are gone
ax[2][0].plot([2,5,3,7])
ax[4][2].plot([2,3,7])
# make legend in upper-right axes (GridSpec's first row, last column)
# first index: 0
# second index: nn-1
rx, cx = 0, nn-1
ax[rx][cx] = fig.add_subplot(gs[rx,cx])
hdl = ax[rx][cx].scatter([10], [10], color="k", s=5, zorder=2, label="Targets")
ax[rx][cx].set_axis_off()
#ax[rx][cx].set_visible(True) # already True
ax[rx][cx].set_xticklabels([])
ax[rx][cx].set_yticklabels([])
# plot legend
plt.legend(bbox_to_anchor=(1.0, 1.0), loc='upper right', borderaxespad=0.)
fig.subplots_adjust(hspace=0.00, wspace=0.00)
plt.show
For instance, given the data in a text file:
10:37:18.459 1
10:37:18.659 0
10:37:19.559 1
How could this be displayed as an image that looked like a square wave that correctly represented the high time and low time? I am trying both gnuplot and scipy. The result should ultimately include more than one sensor, and all plots would have to be displayed above one another so as to show a time delta.
The code in the following link creates a square wave from the formulas listed,
link to waveforms. How can the lower waveform (pwm) be driven by the numbers above if they were in a file (to show a high state for 200 ms, then a low state for 100 ms, and finally a high state)?
If I understood your question correctly you want to plot a step function based on timedata. To avoid further guessing please specify in more detail.
In gnuplot there is the plotting style with steps. Check help steps.
Code:
### display waveform as steps
reset sesion
$Data <<EOD
10:37:18.459 1
10:37:18.659 0
10:37:19.559 1
10:37:19.789 0
10:37:20.123 1
10:37:20.456 0
10:37:20.789 1
EOD
set yrange [-0.05:1.2]
myTimeFmt = "%H:%M:%S" # input time format
set format x "%M:%.1S" time # output time format on x axis
plot $Data u (timecolumn(1,myTimeFmt)):2 w steps lc rgb "red" lw 2 ti "my square wave"
### end of code
Result:
The answer I ended up with was:
file_info = os.stat( self.__outfile)
if file_info.st_size:
x,y,z,a = np.genfromtxt( self.__outfile, delimiter=',',unpack=True )
fig = plt.figure(self.__outfile)
ax = fig.add_subplot(111)
fig.canvas.draw()
test_array = [(datetime.datetime.utcfromtimestamp(e2).strftime('%d_%H:%M:%S.%f')).rstrip('0') for e2 in x]
plt.xticks(x, test_array)
l1, = plt.plot(x,y, drawstyle='steps-post')
l2, = plt.plot(x,a-2, drawstyle='steps-post')
l3, = plt.plot(x,z-4, drawstyle='steps-post')
ax.grid()
ax.set_xlabel('Time (s)')
ax.set_ylabel('HIGH/LOW')
ax.set_ylim((-6.5,1.5))
ax.set_title('Sensor Sequence')
fig.autofmt_xdate()
ax.legend([l1,l2, l3],['sprinkler','lights', 'alarm'], loc='lower left')
plt.show()
I had a input file that had convertDateToFloat values in it. That was passed in to this function. The name is perhaps misleading (__outfile), but on the previous function, it was the output.
I want to augmente my data using data generator in keras as below:
datagen = ImageDataGenerator(
featurewise_center=True, # set input mean to 0 over the dataset
samplewise_center=True, # set each sample mean to 0
featurewise_std_normalization=True, # divide inputs by std of the dataset
samplewise_std_normalization=True, # divide each input by its std
zca_whitening=True, # apply ZCA whitening
rotation_range=0, # randomly rotate images in the range (degrees, 0 to 180)
rescale=1./255,
shear_range=0.2,
zoom_range=0,
width_shift_range=0, # randomly shift images horizontally (fraction of total width)
height_shift_range=0, # randomly shift images vertically (fraction of total height)
horizontal_flip=True, # randomly flip images
vertical_flip=True) # randomly flip images
but I use this network for regression not classification. I have my doubts that datagenerator set new output values or not? Because If I used 0 or 1 classification problem then datagenerator could flip or rotate data without changing output but in here it should change output like input. Does that do this?
Thanks in advance.
i want to draw a circle in an histogram with a radius equal to one and origin in x=0 and y=0. Also i want to draw a point and a letter in a particular position: x=0.5 and y=0.86 and a letter 'L_4' near the same position. Is it possible?
Here my code:
clear
reset
# wxt
#set terminal wxt size 350,262 enhanced font 'Verdana,10' persist
# png
set terminal pngcairo size 500,500 enhanced font 'Verdana,10'
set output 'Err_rev3bp.png'
set title "\n"
set label 1 "Reversibility Error\n 3bp mu=0.001" at graph 0.5,1.15 center
set view map
set xlabel 'x_0'
set xrange [*:*]
set ylabel 'y_0'
set yrange [*:*]
#set logscale z
set zlabel 'Err'
set border linewidth 1.0
set key outside
set pm3d at b
set dgrid 100,100
splot 'trecorpi.txt' w pm3d notitle
exit
I use the following command:
set object 10 circle at 0,0 size 1,1 fc rgb "red"
But i can't see the circle.
Thanks
You can't see a circle because you are using splot, which renders 3D plots. Circle is a 2D object and only compatible with plot command instead. There is a polygon object that is compatible with splot, but it seems there is no sphere object available.
set object 1 polygon from 0,0,0 to 1,1,10 to 2,0,0
set object 1 fc rgb "cyan" fillstyle solid 1.0 border lt -1
splot x
I have a Data file which looks like the one below. Now, I wanted to make a histogram chart using column 9, column 10 as errorbars. That works out pretty good. Bubt is there an option only to plot specific rows?
I tried the solution in a another thread that using a ternary operator:
plot 'Härte StS-123 bis 151.txt' using ( ( $0 == 4 || $0 == 6 ) ? $9 : 1/0 ):($9+$10):($9-$10):xticlabels(2)
this plots row 4 and 6 indeed, but leaves an empty space inbetween the datasets.
Is there any other way to achieve this?
Data File:
StS-123a "SBR / THF" 50.10 49.60 49.20 50.70 50.00 49.50 49.85 0.49 0.00974176
StS-123b "SBR / THF" 51.00 50.40 50.40 52.00 52.80 50.60 51.20 0.90 0.017614257
StS-124a "SBR+2phrGraphit" 49.60 49.40 49.30 48.90 49.40 49.10 49.28 0.23 0.004599753
What you may want is the index option to the plot command:
plot 'datafile' index 4 u 9:($9-$10):($9+$10):xticlabels(2), \
'' index 6 u 9:($9-$10):($9+$10):xticlabels(2)
This should plot just the data from the 4th and 6th datasets (rows), albeit with two different styles which you can adjust in the plot command.
Did you want to connect the values from the two datasets? That may be trickier.
If you want to only plot data from the 4th and 6th rows that have data, you can use external commands in gnuplot, like:
plot "<sed '/^$/d' data.dat | sed -n '4p; 6p'" u 9:($9-$10):($9+$10):xticlabels(2)
(This may not be the most compact way to use sed in this case, but it deletes blank lines then returns the 4th and 6th rows.)